Java异常:Exception与Error,checkedException与unCheckedException

1. Java异常类层级结构图

java.lang.Throwable是Java异常的顶级接口,ExceptionError均继承自Throwable

2. Exception和Error有什么区别?

  • Exception:程序本身可以处理的异常,可以通过try-catch进行捕获。Exception又可分为CheckedException(受检异常)和unCheckedException(非受检异常)。
  • Error:程序本身无法处理的异常,无法通过catch进行捕获不建议通过catch进行捕获。例如上图展示的OutOfMemoryError。这类异常发生时,会导致程序终止运行(线程终止)。

3. CheckedExceptionunCheckedException有什么区别?

二者只是逻辑上的分类,并不存在CheckedExceptionunCheckedException接口或类

  • CheckedException即受检查异常:Java代码在编译过程中,如果受检查异常没有被catch或者throws关键字处理的话,就没法通过编译。除了RuntimeException及其子类,其他的Exception类及其子类都是受检查异常,常见的有:IoExceptionClassNotFoundExceptionSQLException等。
  • unCheckedException即非受检查异常:Java代码在编译过程中,即使我们不对其进行处理,编译也可以通过。RuntimeException及其子类都是非受检查异常,常见的有:NullPointExceptionIllegalArgumentExceptionNumberFormatException等。

4. Throwable有哪些常用方法?

  • String getMessage():返回异常描述信息

  • void printStackTrace():在控制台打印Throwable对象封装的异常信息

5. try-with-resources代替try-catch-finally进行资源释放

try-with-resources是JDK1.7推出的一种资源释放的方式。

  1. 适用范围:资源的定义,任何实现java.lang.AutoCloseablejava.lang.Closeable接口的对象。
  2. 关闭资源和finally块的执行顺序:在try-with-resources语句中,任何catch或finally块在声明的资源关闭后运行。
  3. 使用说明:只需在try后面跟上小括号()括号中对资源进行定义,无需使用finally手动释放资源。

《Effective Java》中明确指出:

面对必须要关闭的资源,我们总是优先使用try-with-resources而不是finally。随之产生的代码更简短,更清晰。

Java中类似于InputStreamOutputStreamScannerPrintWriter等资源都需要我们调用close()方法进行手动关闭资源,一般情况下我们可以使用try-catch-finally来实现:

1
2
3
4
5
6
7
8
9
10
Scanner scanner = null;
try {
scanner = new Scanner(new File("read.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}

JDK1.7后使用try-with-resources实现:

1
2
3
4
5
6
7
try (Scanner scanner = new Scanner(new File("read.txt"))){
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}

涉及到多个资源的定义,使用分号;进行分隔

1
2
3
4
5
6
7
8
try (Scanner scanner = new Scanner(new File("read.txt")); 
OutputStream outputStream = new FileOutputStream("output.txt")){
while (scanner.hasNext()) {
outputStream.write(scanner.nextLine().getBytes(StandardCharsets.UTF_8));
}
} catch (IOException e) {
e.printStackTrace();
}