Skip to content
  1. Error和Exception的区别
  2. throw 和 throws 的区别是什么?
  3. final、finally、finalize 有什么区别?

java异常面试题(2021最新版) - 腾讯云开发者社区-腾讯云

异常体系架构

Java异常是Java提供的一种识别及响应错误的一致性机制。 image.png

Throwble

Throwable Throwable 是 Java 语言中所有错误与异常的超类。 Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。

Error(错误)

定义:Error 类及其子类。程序中无法处理的错误,表示运行应用程序中出现了严重的错误。 特点:此类错误一般表示**代码运行时 JVM **出现问题。通常有

  • Virtual MachineError(虚拟机运行错误)
  • NoClassDefFoundError(类定义错误)
  • OutOfMemoryError:内存不足错误;
  • StackOverflflowError:栈溢出错误。

此类错误发生时,JVM 将终止线程。这些错误是不受检异常,非代码性错误。因此,当此类错误发生时,应用程序不应该去处理此类错误。

Exception(异常)

程序本身可以捕获并且可以处理的异常。Exception 这种异常又分为两类:运行时异常和编译时异常。

运行时异常

定义:RuntimeException 类及其子类,表示 JVM 在运行期间可能出现的异常。 特点:Java 编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既"没有通过throws声明抛出它",也"没有用try-catch语句捕获它",还是会编译通过。 常见的运行时异常有:

  • NullPointerException空指针异常、
  • ArrayIndexOutBoundException数组下标越界异常、
  • ClassCastException类型转换异常、
  • ArithmeticExecption算术异常。

此类异常属于不受检异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。虽然 Java 编译器不会检查运行时异常,但是我们也可以通过 throws 进行声明抛出,也可以通过 try-catch 对它进行捕获处理。如果产生运行时异常,则需要通过修改代码来进行避免。例如,若会发生除数为零的情况,则需要通过代码避免该情况的发生! RuntimeException 异常会由 Java 虚拟机自动抛出并自动捕获(就算我们没写异常捕获语句运行时也会抛出错误!!),此类异常的出现绝大数情况是代码本身有问题应该从逻辑上去解决并改进代码。

编译时异常

定义: Exception 中除 RuntimeException 及其子类之外的异常。 特点: Java 编译器会检查它。 常见的编译时异常有:

  • ClassNotFoundException(没有找到指定的类异常)
  • IOException(IO流异常)

这一类异常要么通过throws进行声明抛出,要么通过trycatch进行捕获处理,否则不能通过编译。在程序中,通常不会自定义该类异常,而是直接使用系 统提供的异常类。该异常我们必须手动在代码里添加捕获语句来处理该异常。

Java的异常关键字

  1. try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
  2. catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
  3. finally – finally语句块总是会被执行。它主要用于回收在try块里打开的资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
  4. throw – 用于抛出异常。
  5. throws – 用在方法签名中,用于声明该方法可能抛出的异常。

Java的异常处理

一般来说异常的处理方式有三种:声明异常,抛出异常,捕获异常 具体如何选择异常的处理方式: image.png

声明异常

应该捕获那些知道如何处理的异常,将不知道如何处理的异常继续传递下去。传递异常可以在方法签名处使用** throws **关键字声明可能会抛出的异常。 非检查异常(Error、RuntimeException 或它们的子类)不可使用 throws 关键字来声明要抛出的异常。

java
private static void readFile(String filePath) throws IOException {
	File file = new File(filePath);
	String result;
	BufferedReader reader = new BufferedReader(new FileReader(file));
	while((result = reader.readLine())!=null) {
		System.out.println(result);
	}
	reader.close();
}

抛出异常

如果你觉得解决不了某些异常问题,且不需要调用者处理,那么你可以抛出异常。 throw关键字作用是在方法内部抛出一个 Throwable 类型的异常。任何Java代码都可以通过throw语句抛出异常。

捕获异常

程序通常在运行之前不报错,但是运行后可能会出现某些未知的错误,但是还不想直接抛出到上一级,那么就需要通过**try…catch…**的形式进行异常捕获,之后根据不同的异常情况来进行相应的处理。

throw和throws的区别

throw 关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。 throws 关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用 throws 标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法签名中用 throws 关键字声明相应的异常。

final、finally、finalize 有什么区别?

final(关键字):可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。 finally(用于异常处理):一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。 finalize(用于垃圾回收):是一个方法,属于Object类的一个方法,而Object类是所有类的父类,Java 中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。