异常

目录

一、Error

二、Exception

2.1 运行时异常RuntimeException

2.2 其他异常

2.3 受检异常和非受检异常

2.4 异常处理机制

2.4.1 try-catch-finally

2.4.2 throws

2.4.3 抓抛模型

三、Throwable类

四、常见面试题

4.1 Exception和Error有什么区别?

4.2 受检异常和非受检异常有什么区别?

 4.3 如何处理异常?

 4.4 finally总是会被执行吗?


所有的异常都是由Throwable类继承而来,Throwable又分为了Error类和Exception类

一、Error

Java运行时系统的内部错误和资源耗尽错误

表示比较严重的问题,一般是JVM运行时出现了错误,如没有内存可分配抛出OOM错误、栈资源耗尽抛出StackOverflowError错误、Java虚拟机运行错误Virtual MachineError、类定义错误NoClassDefFoundError。

如果出现了这样的内部错误,除了通告给用户,并尽力使程序安全地终止之外,再也无能为力了。

二、Exception

异常又分为RuntimeException和其他异常

程序错误导致的异常属于RuntimeException,而程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常

2.1 运行时异常RuntimeException

顾名思义,运行时才可能抛出的异常,编译器不会处理此类异常。比如数组索引越界、使用的对象为空、强制类型转换错误、除0等等。出现了运行时异常,一般是程序的逻辑有问题,是程序自身的问题而非外部因素

2.2 其他异常

Exception中除了运行时异常之外的,都属于其他异常,也可以称为编译时异常,这部分异常编译器必须处置。这部分异常往往是因为外部运行环境导致,因为程序可能运行在各种环境中。编译器要求Java程序必须捕获或声明所有的编译时异常,强制要求程序为可能出现的异常做准备工作。

 

不要被运行时异常的名称所迷惑,理论上所有的错误都是运行时发生的。包括Error、RuntimeException、编译时 异常等等。所有的这些都只能在程序运行的过程中才能碰到。编译时异常指的是编译器要求必须处理的异常,并不是代码编译间发生的错误。

2.3 受检异常和非受检异常

接受检查的异常和不接受检查的异常

Error和RuntimeException运行时异常都不能被检查。他们都是程序运行过程中所产生的,只是 Error的错误比较严重,一般是JVM产生,而RuntimeException⼀般是程序逻辑自身的问题。

受检异常就是编译时异常,这些异常在编译时被强制要求捕获或者声明。编译器将会为所有的受检异常提供异常处理器。

2.4 异常处理机制

主要是try-catch-finally和throw、throws关键字

受检异常只有两种选择。要么被捕获处理,要么被抛出,让调用者处理。

2.4.1 try-catch-finally

try-catch-finally用来捕获异常

try中放可能存在异常的方法

1、如果在try语句块中的任何代码抛出了一个在catch子句中说明的异常类,那么程序将跳过try语句块的其余代码,并且执行catch子句中的处理器代码

2、如果try语句块中的代码没有抛出任何异常,那么程序将跳过catch子句

3、如果方法中的任何代码抛出了catch子句中没有声明的异常类型,那么这个方法就会立刻退出

finally一般用来关闭所占用的资源。如果代码抛出异常,就会终止剩余代码的处理,并且退出这个方法。这样可能会导致一些程序占用的系统不能被正确的释放,而不管是否有异常被捕获,finally中子句的代码都会被执行,可以在这里正确的释放资源。

但是如果try或者catch中出现了System.exit()语句,则会直接退出,不会执行finally模块。

 1、finally中没有return语句 最后返回值为2

int i = 1;
try {
 i = 2;
 return i;
} catch (Exception e) {
} finally {
 i = 3;
}

2、 finally中有return语句 最后返回值为3

int i=1;
try {
 i = 2;
 return i;
} catch (Exception e) {
} finally {
 i = 3;
 return i;
}

 上⾯两个代码只是在finally中是否存在return语句的区别,但直接结果却并不相同。

可以看到如果finally中没有return语句,程序就会把finally中的操纵数据忽略掉。

其实finally中的数据操作也是执行了的,但是并没有返回。这是因为在return语句返回之前,虚拟机会将待返回的值压入操作数栈,等待返回。即使 finally 语句块对 i 进行了修改,但是待返回的值已经确实的存在于操作数栈中了,所以不会影响程序返回结果。

在try中的数据处理完,检测到有return语句时,会先将数据压入操作数栈等待返回,然后去执行finally语句,如果 finally语句没有将新的结果压入操作数栈,那么只可能返回原先的结果

从这个角度理解,即使finally中对数据处理,但是返回的依旧时try中的“脏数据”。

finally并不是没有执行,而是执行了却没有没返回。添加return语句则会将finally处理过的数据压入操作数栈返回,原先的“脏数据”失效。

2.4.2 throws

throws用来声明异常,关注点是受检异常

 

2.4.3 抓抛模型

try-catch-finally是抓,throw/throws是抛。一个类遇到异常,要么捕获后处理,要么继续向上抛出,让调用者进行处理。

catch中可以为空,不进行处理本身就是一种处理方式。

try-catch-finally可以灵活组合

可以try-catch、try-finally或者try-catch-finally

1、try中执行正常,忽略catch,最后执行finally。

2、try中出现异常,且异常在catch中声明,执行catch,最后执行finally。

3、try中出现异常,但catch中未声明,不执行catch,最后执行finally。

4、try中出现异常,且异常在catch中声明,执行catch时出现异常,停止catch中代码,执行finally并且抛出catch 中新出现的异常。

三、Throwable类

主要方法:

1、public String getMessage():返回关于发生的异常的详细信息

2、public Throwable getCause():返回一个Throwable对象代表异常原因

3、public String toString():使用getMessage()的结果返回类的串级名字

四、常见面试题

4.1 Exception和Error有什么区别?

两者都派生自Throwable类的子类

1、Exception类及其子类主要用于表示程序可以处理的异常情况。异常分为两种类型:受检异常和不受检异常。程序员可以选择捕获并处理异常,也可以通过在方法签名中使用throws关键字声明方法可能抛出的异常

2、Error类及其子类通常表示虚拟机无法恢复的严重错误。错误不应该由应用程序捕获和处理,因为它们通常表示虚拟机或系统本身的问题。一般情况下,程序员不会直接捕获和处理Error。这些错误的发生通常意味着程序无法继续正常执行

4.2 受检异常和非受检异常有什么区别?

 1、受检异常是编译时异常,程序员必须处理或声明这些异常。如果不处理,编译器将报错。通常派生自Exception类及其子类,但不派生自RuntimeException

2、非受检异常是运行时异常,通常是由编程错误导致的。这些异常通常派生自RuntimeException或其子类。程序员可以选择处理这些异常,但不是强制的

 4.3 如何处理异常?

 try-catch-finally

try:包裹业务代码

catch:捕获和处理异常

finally:回收资源

try {
 // 代码块,可能会抛出异常
 // 可能抛出异常的代码
} catch (ExceptionType1 e1) {
 // 处理 ExceptionType1 类型的异常
} catch (ExceptionType2 e2) {
 // 处理 ExceptionType2 类型的异常
} finally {
 // ⽆论是否发⽣异常,都会执⾏的代码块
}

 4.4 finally总是会被执行吗?

一般来说,finally块都会在try或catch块执行完毕后被执行,即使发生了异常。然而,有一些情况下,finally块可能不会执行,主要是在以下情况:

1、在try或catch块中调用了System.exit():导致Java虚拟机(JVM)退出

try {
 // ⼀些代码
 System.exit(0); // 这会导致JVM退出,finally块不会执⾏
} finally {
 // 这⾥的代码不会执⾏
}

2、在try块中发生了死循环

try {
 while (true) {
 // ⼀些代码
 }
} finally {
 // 这⾥的代码可能⽆法执⾏
}

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值