目录
1. 错误和异常
Throwable
顾名思义, "可抛出的"类都派生于Throwable
类
//默认的构造器, 没有异常信息, 但也不是什么都不做
Throwable();
//带异常信息的构造器, 将参数字符串作为该异常的异常信息
Throwable(String message);
//带原因的构造器, 把参数异常作为该异常的原因
Throwable(String message, Throwable cause);
//获取异常信息
String getMessage();
Error
内部错误, 资源耗尽错误
无能为力, 只能通知用户并优雅结束
例:
VirtualMachineError
虚拟机错误
LinkageError
链接错误
RuntimeException
源代码错误导致的异常, 程序员的问题
例: 错误强转, 数组越界, 空指针访问
IOException
环境, 用户错误导致的异常
Error
和RuntimeException
统称为unchecked异常
IOException
称为checked异常
2. 异常处理
2.1 创建异常类
该类派生于Exception
或Exception
的某子类
一般包含两个构造器
//默认构造器
OneException() { super(); }
//带详细异常信息的构造器, 内部实现使用super(String)调用Throwable(String)
OneException(...);
2.2 声明异常
异常是方法的第二种退出途径(第一种是返回值).
方法不仅要告诉编译器将要返回什么值, 还要告诉编译器有可能发生什么错误.
在方法首部添加throws ...
, 多个异常类之间用逗号隔开.
void function() throws AException, BException;
不要声明unchecked异常(声明unchecked在静态检查上是合法的, 但不符合逻辑), 必须声明所有可能抛出的checked异常. 这些checked异常或由显式的throw
语句抛出, 或由调用的方法抛出.
2.3 抛出异常(throw)
- 阅读Java API, 寻找合适的异常类; 或自定义异常类
- 实例化并抛出
throw new OneException(...);
方法抛出异常后, 方法会立即退出, 并将控制递交给异常处理器
2.4 捕获异常(catch)
一般来说不应该捕获unchecked异常
2.4.1 try(-catch)*块
try{
//code
//more code
//more and more code
}catch(OneException e){
//handler
}catch(AnotherException e){
//handler
}......
try
中的代码抛出了某catch
子句声明的异常:
跳过try
中剩余代码, 对应catch
块中代码被执行try
中代码未抛出异常
不执行任何catch
块中的代码try
中代码抛出未被catch
子句声明的异常
相当于抛出异常
2.4.2 try(-catch)*(-finally)?块
try{
//code
//more code
//more and more code
}catch(OneException e){
//handler
}finally{
//final code
}
//code code
finally
子句被用来处理try有可能还没来得及完成的任务
优先级 finally
> return
= throw
无论如何 finally
里的语句都会被执行, 而finally
子句之后的代码是否执行取决于是否有未处理的抛出异常
为避免控制流混乱, finally
子句体中不应该含有控制流语句(return
, throw
, break
, continue
)
2.4.3 try-with-resource(-catch)*(-finally)?块
try(Resource r = ...; Resource2 r2 = ...){
//code
//more code
//more and more code
}catch(OneException e){
//handler
}finally{
//final code
}
try
主体使用了一个 / 多个[可关闭]的资源, 且希望在try
主体结束后均将其关闭.
[可关闭]的资源指: 该资源类实现了AutoCloseable
接口, 该接口有一个方法
void close() throws Exception;
AutoCloseable
接口有一子接口Closeable
, 其close
方法为
void close() throws IOException;
try-with-resource语句避免了嵌套使用try-finally
try-with-resource主体退出时会自动调用资源列表中所有资源的.close()
方法
try-with-resource可以有(-catch)*(-finally)?子句, 但这些子句都将在关闭资源后执行
2.5 调用栈轨迹(stack trace)
Throwable
实例的.printStacktrace()
方法可以查看异常的栈轨迹
Stackwalker
实例的.walk()
方法可以查看当前执行位置的栈轨迹