百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

初识java—(四十七)异常处理(java中异常处理机制是怎样的)

lipiwang 2024-11-16 23:20 8 浏览 0 评论

Java的异常机制主要依赖于try、catch、finally、throw和throws五个关键字,其中try关键字后面紧跟着一个花括号括起来的代码块,它里面放置可能会引发异常的代码块。catch后面对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块,多个catch块后面还可以跟一个finally块,用于回收在try块里打开的物理资源,异常机制会保证finally块总会被执行。throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常;而throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象。

10.1 异常概述

异常处理已经成为衡量一门语言是否成熟的标准之一,目前的主流编程语言如C++,C#,Ruby等大都提供了异常处理机制。增加异常处理机制后的程序有更好的容错性,更加健壮。但不代表你这个代码就要随便写了。比如说下面这个代码。

举例1:

public static void main(String[] args) {

List<String> list = new ArrayList<String>();

list.add("abc");

list.add("def");

try {

for(int i=0;i<4;i++){

System.out.println(list.get(i));

}

} catch (IndexOutOfBoundsException e) {

System.out.println("已经超出了集合的范围");

}

}

10.2 异常处理机制

Java的异常处理机制可以让程序具有极好的容错性,让程序更加健壮。当程序出现意外情形时,系统会自动生成一个Exception对象来通知程序,从而实现将“业务功能实现代码”和“错误处理代码”分离,提供更好的可读性。

10.2.1 使用try…catch捕获异常

在Java中提出了一种假设:如果程序可以顺利完成,那就“一切OK”,把系统的业务实现代码放在try块中定义,所有的异常处理逻辑放在catch块中进行处理。下面是Java异常处理机制的语法规则。

try{

//业务实现代码

}catch(ExceptionClass1 e1){

//错误处理代码

}catch(ExceptionClass2 e2){

//错误处理代码

}finally{

//始终会执行的代码

}

Try块后可以有多个catch块,这是为了针对不同的异常类提供不同的异常处理方式。当系统发生不同的意外情况时,系统会生成不同的异常对象,Java运行时就会根据该异常对象所属的异常类来决定使用哪个catch块来处理。

举例1:

public static void main(String[] args) {

List<String> list = new ArrayList<String>();

list.add("abc");

list.add("def");

list.add(null);

try {

for(int i=0;i<4;i++){

list.get(i).equals("abc");

System.out.println(list.get(i));

}

} catch (IndexOutOfBoundsException e) {

System.out.println("索引值越界异常");

}catch(NullPointerException e){

System.out.println("空指针异常处理");

}finally{

System.out.println("始终会被执行的代码块");

}

}

10.2.2 异常类的继承体系

Java提供了丰富的异常类,这些异常类之间有严格的继承关系,如下图所示:



在Java中把所有的非正常情况分为两种:异常(Exception)和错误(Error),他们都继承Throwable父类。Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等,这种错误无法恢复或不能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不能试图使用catch块来捕获Error对象,在定义方法时也无须其throws子句中声明该方法可能抛出Error及其任何子类。

10.2.3 访问异常信息

如果程序需要在catch块中访问异常对象的相关信息,则可以通过访问catch块后的异常形参来获得。当Java运行时决定调用某个catch块来处理该异常对象时,会将异常对象赋给catch块后的异常参数,程序即可通过该参数来获得异常的相关信息。

所有异常对象都包含了如下几个常用方法。

? getMessage():返回该异常的详细描述字符串。

? printStackTrace():将该异常的跟踪栈信息输出到标准错误输出。

? printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定输出流中。

? getStackTrace():返回该异常的跟踪栈信息。

举例1:

public static void main(String[] args) {

List<String> list = new ArrayList<String>();

list.add("abc");

list.add("def");

list.add(null);

try {

for(int i=0;i<4;i++){

list.get(i).equals("abc");

System.out.println(list.get(i));

}

} catch (IndexOutOfBoundsException e) {

System.out.println("已经超出了集合的范围");

}catch(NullPointerException e){

e.printStackTrace();

System.out.println(e.getMessage());

System.out.println("空指针异常处理");

}finally{

System.out.println("始终会被执行的代码块");

}

}

输出信息:


10.2.4 使用finally回收资源

程序在try块里打开了一些物理资源,比如:数据库连接、网络连接、和磁盘文件等,这些物理资源都必须显示回收。

如果在try块的某条语句引起了异常,该语句后的其他语句通常不会获得执行的机会,这将导致该语句之后的资源回收语句得不到执行。如果在catch块里进行资源回收,但catch块完全有可能得不到执行,这将导致不能及时回收这些物理资源。

为了保证一定能回收try块中打开的物理资源,异常处理机制提供了finally块。不管try块中的代码是否出现异常,也不管哪一个catch块被执行,甚至在try块或者catch块中执行了return语句,finally块总会被执行。因此回收资源执行语句应该在finally块中执行。

举例1:

public static void main(String[] args) {

FileInputStream fis = null;

try {

fis = new FileInputStream("./a.txt");

} catch (Exception e) {

e.printStackTrace();

return;

}finally{

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

10.2.5 使用throws声明抛出异常

使用throws声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用throws声明抛出异常,该异常将交给JVM处理。JVM对异常的处理方法是,打印异常的跟踪栈信息,并终止程序执行。

举例1:

public void dealFile() throws Exception{

FileInputStream fis = null;

try {

fis = new FileInputStream("./a.txt");

} catch (Exception e) {

fis.close();

e.printStackTrace();

}

}


public static void main(String[] args) throws Exception {

Test test = new Test();

test.dealFile();

}

10.2.6 使用throw抛出异常

如果需要在程序中自主的抛出异常,则应该使用throw语句,throw语句可以单独使用,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例。

举例1:

public static void main(String[] args){

for(int num=5;num>=0;num--){

try {

if(num<2){

throw new Exception("数字的值小于2了,停止运行");

}

} catch (Exception e) {

System.out.println("======");

System.out.println(e.getMessage());

}

}

System.out.println("最终执行完成");

}

异常处理小总结

生活中的异常:出去玩,有严重问题,一般问题,玩之前出现问题,玩的过程中出现问题。


程序的异常:Throwable

严重问题:Error--我们不处理,这种问题一般都是很严重的问题,比如说:内存溢出

一般问题:Excepton

编译期问题:不是RuntimeException:必须进行处理的异常,不处理,编译不会通过。(这就是咱要处理问题)

运行期问题:RuntimeException :无法直接处理,代码问题,需要修改代码


程序出现问题时,我们不处理,最终jvm会进行默认的处理

把异常的名称、原因以及出现的问题等信息输出在控制台上,同时会结束程序,不再执行以后的代码。


我们是如何处理的:

A: try…catch…finally

注意:

(1) try 里边的代码越少越好:放在try里边就要走异常处理机制,jvm就一些新的资源来处理问题。

(2) catch里边必须有内容:eg:TestTryCatch1

(3) 多个catch语句时:一旦try里面出现了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,就直接结束了try…catch,继续执行后面的语句,而不会执行try里边的其它语句。eg:TestTryCatch2

(4) 如果在一个try中不知道是哪里出现了问题,是出现是什么类型的问题?可以在最后一个catch中添加一个Exception的“异常类型”

(5) catch里边的“异常类型”,有明确的要明确。如果直接写Exception的话,jvm会从Exception中来进行查找。而且Exception“异常类型”必须是写在最后边!也就是说,父类必须在最后边!eg:TestTryCatch2

讲解一下编译时异常与运行时异常的区别:

(1) 编译时异常:java程序必须显示处理,否则程序就会发生错误,无法通过编译:eg:TestTryCatch3

(2) 运行时异常:无需显示处理,也可以和编译时异常一样处理

异常中要了解的几个方法:

所有异常对象都包含了几个常用方法:这几个方法是哪里的? Throwable

? getMessage():返回该异常的详细描述字符串。

? printStackTrace():将该异常的跟踪栈信息输出到标准错误输

? printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定输出流中。(咱用这个!)

u 这的内容和jvm默认处理输出一样,但是咱们可以接着执行try..catch后面的内容。eg.TestTrycatch4

Finally:

是异常处理的一部分,用于释放资源。

注意:finally中的代码一般会被执行,但是如果执行到finally之前jvm退出了,就不能执行了。

eg:TestFinally

final,finally,finalize的区别:

final:最终的意思,可以修饰类(不能被继承),成员变量,成员方法(不能被被重写)。

finally:是异常处理的一部分,用于释放资源。finally中的代码一般会被执行,但是如果执行到finally之前jvm退出了,就不能执行了。

finalize:是Object类中的一个方法,用于垃圾回收。


B: thorws 抛出

eg:TestThrows TestThrow

throws和throw的区别:

l throws

? 用在方法声明后面,跟的是异常类名

? 可以跟多个异常类名,用逗号隔开

? 表示抛出异常,由该方法的调用者来处理

? throws表示出现异常的一种可能性,并不一定会发生这些异常

l throw

? 用在方法体内,跟的是异常对象名

? 只能抛出一个异常对象名

? 表示抛出异常,由方法体内的语句处理

? throw则是抛出了异常,执行throw则一定抛出了某种异常

如果catch里面有return语句,请问finally里面的代码还会执行吗?如果会,请问在return之前还是之后 ?

答案:会执行,之前执行。

相关推荐

前端入门——css 网格轨道详细介绍

上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...

Islands Architecture(孤岛架构)在携程新版首页的实践

一、项目背景2022,携程PC版首页终于迎来了首次改版,完成了用户体验与技术栈的全面升级。作为与用户连接的重要入口,旧版PC首页已经陪伴携程走过了22年,承担着重要使命的同时,也遇到了很多问题:维护/...

HTML中script标签中的那些属性

HTML中的<script>标签详解在HTML中,<script>标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用<scrip...

CSS 中各种居中你真的玩明白了么

页面布局中最常见的需求就是元素或者文字居中了,但是根据场景的不同,居中也有简单到复杂各种不同的实现方式,本篇就带大家一起了解下,各种场景下,该如何使用CSS实现居中前言页面布局中最常见的需求就是元...

CSS样式更改——列表、表格和轮廓

上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。1.列表List1).列表的类型<ulstyle='list-...

一文吃透 CSS Flex 布局

原文链接:一文吃透CSSFlex布局教学游戏这里有两个小游戏,可用来练习flex布局。塔防游戏送小青蛙回家Flexbox概述Flexbox布局也叫Flex布局,弹性盒子布局。它决定了...

css实现多行文本的展开收起

背景在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景:那么,如何通过纯css实现这样的效果呢?实现的难点(1)位于多行文本右下角的展开收起按钮。(2)展开和收起两种状态的切换。(3)文本...

css 垂直居中的几种实现方式

前言设计是带有主观色彩的,同样网页设计中的css一样让人摸不头脑。网上列举的实现方式一大把,或许在这里你都看到过,但既然来到这里我希望这篇能让你看有所收获,毕竟这也是前端面试的基础。实现方式备注:...

WordPress固定链接设置

WordPress设置里的最后一项就是固定链接设置,固定链接设置是决定WordPress文章及静态页面URL的重要步骤,从站点的SEO角度来讲也是。固定链接设置决定网站URL,当页面数少的时候,可以一...

面试发愁!吃透 20 道 CSS 核心题,大厂 Offer 轻松拿

前端小伙伴们,是不是一想到面试里的CSS布局题就发愁?写代码时布局总是对不齐,面试官追问兼容性就卡壳,想跳槽却总被“多列等高”“响应式布局”这些问题难住——别担心!从今天起,咱们每天拆解一...

3种CSS清除浮动的方法

今天这篇文章给大家介绍3种CSS清除浮动的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。首先,这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。下面我就讲3种常用清除浮动的...

2025 年 CSS 终于要支持强大的自定义函数了?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是CSS自定义属性CSS自...

css3属性(transform)的一个css3动画小应用

闲言碎语不多讲,咱们说说css3的transform属性:先上效果:效果说明:当鼠标移到a标签的时候,从右上角滑出二维码。实现方法:HTML代码如下:需要说明的一点是,a链接的跳转需要用javasc...

CSS基础知识(七)CSS背景

一、CSS背景属性1.背景颜色(background-color)属性值:transparent(透明的)或color(颜色)2.背景图片(background-image)属性值:none(没有)...

CSS 水平居中方式二

<divid="parent"><!--定义子级元素--><divid="child">居中布局</div>...

取消回复欢迎 发表评论: