异常

Wu Jun 2020-01-01 01:43:49
Categories: > > Tags:

1 异常分类

2 声明异常

已检查异常需要声明,或被捕获。如有多个需要在方法首部列出所有,逗号隔开。

Errors 和 未检查异常不需要声明。因为这类错误本身就是 bug,应该被修复,出现此类错误时程序就应该立即停止执行。

3 抛出异常

throw new Exception();

4 自定义异常

class FileFormatException extends IOException
{
    public FileFormatException() {}
    public FileFormatException(String gripe){
        super(gripe);
    }
}

5 捕获异常

5.1 捕获多个异常

1)基本语句
try{
}catch (FileNotFoundException e){
}catch (UnknownHostException e){
}
2)合并catch语句
try{
}catch (FileNotFoundException | UnknownHostException e){
}

5.2 再次抛出异常

1)基本方法
try{
}catch (SQLException e){
    throw new ServletException("database error: "+e.getMessage());
}
2)保留原始异常
try{
}catch (SQLException e){
    Throwable se=new ServletException("database error");
    se.initCause(e);
    throw se;
}
3)获取原始异常
Throwable e = se.getCause();

5.3 finally 子句

1)基本语法
try{
}catch(Exception e){
}finally{
    in.close();
}
2)建议使用

强烈建议独立使用 try/catch 和 try/finally 语句块,提高代码的清晰度。

InputStream in= ... ;
try{
    try{
        code that might throw exceptions
    }finally{
        in.close();
    }
}catch(IOException e){
    show error message
}

5.4 带资源的 try 语句

1)基本语法

假如资源实现了 AutoCloseable/Closeable 接口。可以利用带资源的 try 语句,try 退出时,会自动调用 res.close()。

try(Resource res=...){
    work with res
}
2)指定多个资源
try (Resource res1=...,Resource res2=...){
    work with res
}

如果 .close() 也抛出了异常,不会覆盖原来该抛出的异常,而是被抑制,可以通过 getSuppressed 方法获取被抑制的异常。

5.5 分析堆栈跟踪

堆栈跟踪(stack trace)是一个方法调用过程的列表。

1)getStackTrace()

得到 StackTraceElement 对象的一个数组。

能获得文件名,类名,当前执行的代码行号

Throwable t = new Throwable();
StackTraceElement[] frames = t.getStackTrace();
for(StackTraceElement f : frames)
    System.out.println(f);
2)Thread.getAllStackTrace

获得所有线程的堆栈跟踪

Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();
for(Thread t : map.keySet())
{
    StackTraceElement[] frames=map.get(t);
    for(StackTraceElement f : frames)
    System.out.println(f);
}