1. 异常类层次结构
Throwable(C): Throwable类是Java语言中所有错误或异常的超类。
|
|--Error(C): Error是Throwable的子类,表明一个合理的应用程序不应该试图捕获的严重问题。
| |
| |--OutOfMemoryError(C):内存溢出
| |
| |--StackOverflowError(C):栈溢出
| |
| |--NoClassDefFoundError(C):Java虚拟机或ClassLoader实例无法找到该类的定义。
| |
| |--ExceptionInInitializerError(C):静态变量未初始化错误。
| |...
|
|--Exception(C)
| |
| |--IOException(C):I/O异常
| |
| |--SQLException(C):数据库访问相关异常
| |
| |--ClassNotFoundException(C):通过字符串名加载类时,没有找到具有指定名称的类的定义异常,比如Class.forName(className)
| |
| |--NoSuchMethodException(D):无法找到某一特定方法异常
| |...
| |
| |
| |--RuntimeException(C):运行时异常(非检查型异常,可以不用在方法里捕获或抛出的异常)
| | |
| | |--ClassCastException(C):类型强制转换异常
| | |
| | |--IllegalArgumentException(C):非法参数异常(向方法传递了一个不合法或不正确的参数)
| | |
| | |--IndexOutOfBoundsException(C):索引越界异常
| | |
| | |--NullPointerException(C):空指针异常
| | |
| | |--ArraylndexOutOffloundsException(C):数字索引越界异常
| | |...
2. 异常捕获代码结构
2.1 try/catch/finally 语句块
try {
// code
} catch (FileNotFoundException e) {
// action
} catch (IOException e) {
// action
} finally {
// 不管是否有异常被捕获, finally 子句中的代码都被执行。
}
2.2 带资源的try语句
- 如果资源类实现了 AutoCloseable 接口,try 块正常退出,或存在异常,都会调用 in.close() 方法,就好像使用了 finally 块一样。
try (Scanner in = new Scanner(new FileInputStream("a.txt")) , "UTF-8")
{
while (in.hasNext())
System.out.println(in.next()) ;
}
3. 在 try/catch/finally 中的 return 问题
@Test
public void myTest() {
System.out.println(getA1()); // 输出为:finally 2
System.out.println(getA2()); // 输出为:finally 2
}
public int getA1() {
int a = 1;
try {
return a + 1;
} catch (Exception e) {
e.printStackTrace();
} finally {
a = a + 2;
System.out.print("finally ");
}
return a;
}
public int getA2() {
int a = 1;
try {
a = 1/0;
} catch (Exception e) {
e.printStackTrace();
return a + 1;
} finally {
a = a + 2;
System.out.print("finally ");
}
return a;
}
4. try-with-resources 自动关闭资源
- 如果资源实现了 AutoCloseable 或 Closeable 接口,可以使用 try-with-resources 的 try 块来声明和初始化资源。
- 资源的声明必须在圆括号内,资源会在 try 块退出时自动关闭。
- 此语法还可以包括一个 catch 块来处理可能抛出的异常。
语法:
try (Resource1 resource1 = new Resource1();
Resource2 resource2 = new Resource2();
Resource3 resource3 = new Resource3()) {
// 使用 resource1、resource2、resource3
} catch (Exception e) {
// 处理异常
}
在这里,resource1、resource2、resource3 都会自动关闭
但是资源的关闭顺序与它们的声明顺序相反,即最后声明的资源最先关闭。
关闭了 Resource3 资源
关闭了 Resource2 资源
关闭了 Resource1 资源