转载

异常处理

异常继承层次

异常处理

注:图片出自《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不能为空");  
}
原文  https://segmentfault.com/a/1190000021420686
正文到此结束
Loading...