Java面试八股文(2023最新)--Java异常面试题

目录

1. Java异常是什么?

2. Java异常架构

3. Java异常关键字

4.Java异常处理

5. Error和Exception的区别是什么?

6. 运行时异常和一般异常(受检异常)区别是什么?

7. JVM是如何处理异常?

8. throw和throws的区别

9. NoClassDefFoundError和ClassNotFoundException区别?

10. try-catch-finally中哪个部分可以省略?

11. try-catch-finally中如果catch中return,finally还会执行吗?

12. 常见的RuntimeException有哪些?


1. Java异常是什么?

  • Java异常是Java提供的一种识别以及响应错误的一致性机制
  • Java异常可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答what,where,why:异常类型回答了什么被抛出,异常堆栈跟踪回答了在哪被抛出,异常信息回答了为什么会抛出

2. Java异常架构

  1.  Throwable
    1. Throwable是Java语言中所有错误与异常的超类
    2. Throwable包含两个子类:Error(错误),Exception(异常),他们通常用于指示发生了异常的情况
    3. Throwable包含了其线程创建时线程执行堆栈的快照,提供了pringStackTrace()等接口用于获取堆栈跟踪数据等信息
  2. Error(错误)
    • 定义:Error类及其子类。程序中无法处理的错误,表示运行程序中出现了严重的错误
    • 特点:此类错误一般表示代码运行时JVM出现问题,通常有Virtual MachineError(虚拟机运行错误),NoClassDefFoundError(类定义错误),OutOfMemoryError(内存不足错误),StackOverflowError(栈溢出错误,此类错误发生,JVM终止线程)
      注意:以上这些错误不受检异常,非代码性错误。因此,当此类错误发生,应用程序不应该去处理此类错误。按照Java惯例,我们是不应该实现任何新的Error子类的!
  3. Exception(异常)
    程序本身可以捕获并且可以处理的异常。Exception的这种异常又分为两类:运行时异常和编译时异常。
    • 运行时异常
      • 定义:RuntimeException类及其子类,表示JVM在运行期间可能出现的异常
      • 特点:Java编译器不会检查,当程序可能出现这种异常,没有通过throws抛出它,也没有try-catch捕捉它,还是会编译通过。比如NullPointerException空指针异常,ArrayIndexOutBoundException数组下标越界异常,ClassCastException类型转换异常,ArithmeticException算数异常等,此类异常是不受检异常,一般是程序逻辑错误导致。
      • RuntimeException异常会由Java虚拟机自动抛出并自动捕获,此类异常绝大多数是代码本身有问题,应该从逻辑上区解决并改进
    • 编译时异常
      • 定义:Exception中除去RuntimeException及其子类之外的异常。
      • 特点:Java编辑器会检查它,如果程序出现此类异常,比如ClassNotFoundException(没有找到指定类异常),IOException(IO流异常),要么通过throws声明抛出,要么try-catch捕获,否则不通过编译。该类异常我们必须通过手动抛出或者捕获

3. Java异常关键字

  • try:用于监听。将要被监听的代码放在try语句块内,当try代码出现异常则抛出
  • catch:用来捕获try语句块中的异常
  • finally:该语句块内代码总是会被执行。主要用于回收try打开的资源(数据库连接,网络连接,磁盘文件等)。只有finally执行完成,才会回来执行try或者catch块中的return或throws语句,如果finally使用了return或throws等终止方法语句,则不会跳回,直接会停止
  • throws:一般在方法名后,用于声明该方法可能抛出异常
  • throw:用于抛出异常

4.Java异常处理

  • Java通过面向对象的方法进行异常处理,一旦方法抛出异常,系统自动根据该异常对象寻找合适异常处理器(ExceptionHandler)来处理该异常,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象包含异常信息,调用这对象方法可以捕获到这个异常并可以对其进行处理。Java的异常处理是通过5个关键字实现:try,catch,throw,finally,throws
  • 在Java应用中,异常处理机制分为声明异常,抛出异常和捕获异常
  • 1. 声明异常
    •  通常,应该捕获那些知道如何处理的异常,将不知道如何处理的异常继续传递下去。传递异常可以在方法签名处使用throws关键字声明可能抛出的异常
    • 注意:
      • 非检查异常(Error,RuntimeException或它的子类)不可使用throws关键字声明抛出的异常
      • 一个方法出现编译时异常,需要try-catch或thrwos处理
  • 2. 抛出异常
    • 如果你觉得解决不了某些一场问题,且不需要调用者处理,那么你可以抛出异常
    • throw关键字的作用是在方法内部抛出一个Throwable类型的异常。任何java代码都可以通过throw语句抛出
  • 3. 捕获异常
    • 程序通常在运行之前不报错,但是运行后报错,但不想直接抛出到上一级,那么就需要try-catch进行异常捕获,之后根据不同的异常情况来进行相应的处理。

5. Error和Exception的区别是什么?

  • Error类型错误通常为虚拟机相关错误,例如程序崩溃,内存不足,堆栈溢出等
  • Exception类的错误可以在程序中进行捕获并处理的,通常遇见这种错误,应对其处理,使程序可以运行

6. 运行时异常和一般异常(受检异常)区别是什么?

  • 运行时异常:包括RuntimeException类及其子类,表示JVM运行中出现的异常
  • 受检异常:是Exception除了RuntimeException及其子类之外的异常。Java编译器会检查受检异常。
  • 一般来讲,没有特殊要求,建议使用RuntimeException异常

7. JVM是如何处理异常?

  • 在一个方法中如果发生异常,这个方法会创建一个异常对象,转交给JVM,该异常对象包括异常名称,描述,异常发生时应用状态。创建异常对象并转交给JVM的过程称为抛出异常。可能有一系列的方法调用,最终进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈
  • JVM会顺着调用栈去查看是否有去可以处理的异常代码,如果有,则调用异常代码。当JVM发现可以处理异常的代码时,会把发生的异常传递给它。如果JVM没有找到可以处理的该异常的代码块,JVM就会将该一场转交给默认的异常处理器(默认处理器为JVM的一部分),默认异常处理器打印出异常信息并终止应用程序

8. throw和throws的区别

  • Java中异常处理除了捕获异常和处理异常之外,还包括声明式异常和抛出异常,可以通过throws关键字在方法声明要抛出的异常,或者在内部通过throw抛出
    • throw:用于方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常。
    • throws:用于方法声明上,可以抛出多个异常。

9. NoClassDefFoundError和ClassNotFoundException区别?

  • NoClassDefFoundError:是一个Error类型的异常,由JVM引起,该异常引起的原因是JVM或者CLassLoader尝试加载某类时在内存中找不到该类的定义,发生在运行期间
  • ClassNotFoundException:是一个受检异常,需要显式地使用try-catch对其进行捕获和处理,或在方法签名处使用throws关键字声明。当使用Class.forName,ClassLoad.loadClass或ClassLoader.findSystemClass动态加载类到内存的时候,通过传入的类路径参数没有找到该类,就会抛出异常;另一种可能是某个类已经被加载到内存,另一个类加载器又去加载它。

10. try-catch-finally中哪个部分可以省略?

catch可以省略

原因:

  • 严格的说其实是:try只适合处理运行时异常,try+catch适合处理运行时异常+普通异常,也就是说,如果你只用try处理普通异常却不加catch处理,编译是不通的,因为编译器硬性规定,普通异常如果选择捕获,必须catch显示声明以便进一步处理,而运行时异常在编译时没有规定,所以catch可以省略。
  • 理论上,编译器看任何代码都觉得可能存在潜在问题,所以你即使给所有代码加上try,代码在运行时其也只不过是在正常运行的基础上加一层皮,但你一旦对代码加上try,等于承诺编译器,对这段代码可能抛出的异常进行捕获而并非向上抛出,如果是普通异常,编译器必要用catch捕获;如果是运行时异常,捕获然后丢弃并且+finally扫尾处理,或者加上catch捕获,进一步处理。
  • 至于finally,无论有没有捕获异常,都要执行。

11. try-catch-finally中如果catch中return,finally还会执行吗?

会执行,在return前执行

  • 注意:如果存在finally代码块,try中的return语句不会立马返回,而是记录下返回值等待finally执行完再向调用者返回其值,然后如果在finally中修改了返回值,就会返回修改后的值。再finally返回或修改返回值会给程序带来跟大困扰。
  • 代码示例:
public static int getInt() {
    int a = 10;
    try {
        System.out.println(a / 0);
        a = 20;
} catch (ArithmeticException e) {
        a = 30;
        return a;
/*
* return a 在程序执行到这一步的时候,这里不是return a 而是 return 30;这个返回
路径就形成了
* 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
* 再次回到以前的路径,继续走return 30,形成返回路径之后,这里的a就不是a变量了,而是
常量30
*/
    } finally {
        a = 40;
    }
    return a;
}
//执行结果30

12. 常见的RuntimeException有哪些?

  • ClassCastException(类转换异常)
  • IndexOutOfBoundException(数组越界)
  • NullPOinterException(空指针)
  • ArrayStoreException(数组存储异常,操作数组时类型不一致)
  • BufferOverflowException(IO操作异常)

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月月崽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值