异常继承层次
注:图片出自《Core Java SE 9 for the Impatient》
图5-1显示了java中的异常继承层次。当发生了某种异常,而这种异常不是期望应用程序处理的,比如内存耗尽,则会抛出Error之类的异常。
程序员报告的异常属于Exception类的子类。它们分为两种:
- 未检查异常,属于RuntimeException的子类。
- 所有其他异常都是已检查异常。
已检查异常常用于错误可被提前预知的情况,比如:常见的错误原因是输入和输出、指定路径的文件未找到等。
未检查异常表明程序员造成的逻辑错误,不是不可避免的外部风险导致的。
已检查异常的声明
列出方法可能会抛出的异常,这些异常要么是方法本身通过throw语句抛出,要么调用另外一个带throws语句的方法来声明异常。
例子:
//声明异常
public static void Write1 (Object obj, String fileName) throws IOException, ReflectiveOperationException {
}
//方法本身先抛出异常,后捕获
public static void Write2 (Object obj, String fileName) {
try {
throw new IOException();
} catch (Exception e) {
e.printStackTrace();
}
}
异常捕获
对于不同的异常类可以有多个异常处理器。
例子:
try {
} catch (ExceptionClass1 e) {
}catch (ExceptionClass1 e) {
}catch (Exception e) {
}
try-with-resources语句
资源管理是异常处理中需要关注的问题之一。
例如:你向一个文件写入内容,当写操作完成后,关闭文件。
例子:
List<String> lines = new ArrayList<>();
PrintWriter out = new PrintWriter("TempOutput.txt");
for (String line: lines) {
out.println(line.toLowerCase());
}
out.close();//释放资源,如果任意一个地方出现异常,则out.close()将不会执行。
//改进版:
List<String> lines = new ArrayList<>();
try(PrintWriter out = new PrintWriter("TempOutput.txt")){
for (String line: lines) {
out.println(line.toLowerCase());
}
}
在使用try语句的这种特定形式的前提是:这些资源必须属于实现了AutoCloseable接口的类。
finally子句
try{}finally{} 或 try-catch-finally形式的语句
当try到达末尾时,不管是正常完成还是异常导致的,都会执行finally子句。用于清除一些没有AutoCloseable接口的资源等等。
//这是AutoCloseable接口
public interface Closeable extends AutoCloseable {
public void close() throws IOException;
}
但是你必须要小心finally子句中的异常。
例子:
BufferedReader in = null;
try
{
Path path = null;
in = Files.newBufferedReader(path, StandardCharsets.UTF\_8);
}catch (Exception ex){
System.out.println(ex.getMessage());
}
finally {
if(in != null){
in.close(); //可能抛出异常
}
}
//改进版:
BufferedReader in = null;
try
{
Path path = null;
in = Files.newBufferedReader(path, StandardCharsets.UTF\_8);
}catch (Exception ex){
System.out.println(ex.getMessage());
}
finally {
try
{
if(in != null){
in.close();
}
}catch (Exception ex)
{
System.out.println(ex.getMessage());
}
}
//或者改为
Path path = null;
try(BufferedReader in = Files.newBufferedReader(path, StandardCharsets.UTF_8))
{
}catch (Exception ex){
System.out.println(ex.getMessage());
}
Objects.requireNonNull方法
使用Objects.requireNonNull便于检测参数是否为空,如果参数为空,马上抛出NullPointerException异常,你马上就能知道哪里出错了。该方法更多的变体请自行查阅api。
public static void Process(String data)
{
Objects.requireNonNull(data,"data不能为空");
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。