人非圣贤,孰能无过,更况且是程序员.因此排错也是我猿的一项基本技能.java
排错要先知道有哪些错,先上图,而后一项一项分析!程序员
这个类的接口基本决定着java全部异常的行为,好比经常使用在catch中getMessage(),printStackTrace().其余详细以下编程
返回类型安全
方法名称jvm
方法说明编辑器
Throwableide
fillInStackTrace()工具
在异常堆栈跟踪中填充。post
Throwable
getCause()
返回此 throwable 的 cause;若是 cause 不存在或未知,则返回 null。
String
getLocalizedMessage()
建立此 throwable 的本地化描述。
String
getMessage()
返回此 throwable 的详细消息字符串。
StackTraceElement[]
getStackTrace()
提供编程访问由 printStackTrace() 输出的堆栈跟踪信息。
Throwable
initCause(Throwable cause)
将此 throwable 的 cause 初始化为指定值。
void
printStackTrace()
将此 throwable 及其追踪输出至标准错误流。
void
printStackTrace(PrintStream s)
将此 throwable 及其追踪输出到指定的输出流。
void
printStackTrace(PrintWriter s)
将此 throwable 及其追踪输出到指定的 PrintWriter。
void
setStackTrace(StackTraceElement[] stackTrace)
设置将由 getStackTrace() 返回,并由 printStackTrace() 和相关方法输出的堆栈跟踪元素。
String
toString()
返回此 throwable 的简短描述。
error:系统级别的异常.该错误像运行时堆溢出,属于代码级不可控范畴.
exception:应用级异常,属于代码级可控异常.因此自定义的异常都须要继承这个接口. 同时exception也包括以下两类.
家喻户晓,java中经过try catch来捕捉异常,打到日志里为排错提供依据.下面对try catch的一些场景进行分析,照例先上一段案例代码
public class TestTryCatch { public static void main(String[] args) { System.out.println(returnInt()); } public static int returnInt(){ int x; try { x = 1; return x; } catch (NullPointerException e) { x = 2; return x; } finally { x = 3; } } }
jvm的try catch 逻辑是经过Exception table条件来实现的,在from到to的计数行数中爆出的异常从上向下比对type类型,符合的则修改程序计数器中的行数到target指示的行数.
public static int returnInt(); descriptor: ()I flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=4, args_size=0 0: iconst_1 //取1放到栈顶 ---->是try块中的开始 1: istore_0 //从栈顶将数值放到本地变量(局部变量表第0个变量) 2: iload_0 //保存x到returnValue中 ---->是try块中的结束 3: istore_1 ---->是finally块中的开始(没报错) 4: iconst_3 //取3放到栈顶 5: istore_0 //从栈顶将数值放到本地变量(局部变量表第0个变量) ---->是finally块中的结束(没报错) 6: iload_1 7: ireturn //返回结果 8: astore_1 //给catch中定义的Exception e赋值 ---->是catch块中的开始 9: iconst_2 //catch块中的x=2 10: istore_0 11: iload_0 12: istore_2 // ---->是catch块中的结束 13: iconst_3 //finaly块中的x=3 ---->是finally块中的开始(catch到异常) 14: istore_0 15: iload_2 16: ireturn //返回结果 ---->是finally块中的结束(catch到异常) 17: astore_3 //若是出现了不属于java.lang.NullPointerException及其子类的异常才会走到这里 18: iconst_3 //finaly块中的x=3 ---->是finally块中的开始(没catch到异常) 19: istore_0 20: aload_3 //将异常放置到栈顶,并抛出 21: athrow // ---->是finally块中的结束(没catch到异常) Exception table: from to target type 0 4 8 Class java/lang/NullPointerException 0 4 17 any 8 13 17 any
同时从字节码能够看出有以下结果(都假设在x赋值后,return前报错):
从上能够得出结论
不要在 finally 块中使用 return. 通过测试若是finally中加了retrun x;则字节码中不会出现athrow,而是变为以下ireturn,因此使用的时候须要注意finally中若是有return那么异常将不会被抛出.
...... 23: astore_3 24: iconst_3 25: istore_0 26: iload_0 27: ireturn Exception table: from to target type 0 7 11 Class java/lang/NullPointerException 0 7 23 any 11 19 23 any
在阿里泰山版开发手册中也有说明.
例如这样一个场景:try中出现了报错,可是进入到finally执行关闭io的时候也报了错,那么结果是方法只会抛出finally中报的错.addSuppressed能够用来解决这个问题,能够同时将try中的错误跟finally中的错误都抛出.代码举例以下:
public static int returnInt() throws IOException{ IOException e = null; int x = 0; try { x = 1; dothing(); return x; }catch (IOException e1){ e = e1; x = 2; return x; }finally { x = 3; try { dothing(); }catch (IOException e2){ if(e != null){ //注意这里 e.addSuppressed(e2); }else{ e = e2; } } if(e != null){ throw e; } } }
不止各位看官是否以为上面addSuppressed的书写方法特别的繁琐呢,1.7版本的try-catch-resource经过让资源实现AutoClosable中的close来实现无需手写,自动调用关闭逻辑的功能;举例代码:
public class Connection implements AutoCloseable { public void sendData() { System.out.println("正在发送数据"); } @Override public void close() throws Exception { System.out.println("正在关闭链接"); } } --------------------------------------------------- public class TryWithResource { public static void main(String[] args) { try (Connection conn = new Connection()) { conn.sendData(); } catch (Exception e) { e.printStackTrace(); } } }
而后将代码放在idea里面查看反编译代码
public class TryWithResource { public TryWithResource() { } public static void main(String[] args) { try { Connection conn = new Connection(); Throwable var2 = null; try { conn.sendData(); } catch (Throwable var12) { var2 = var12; throw var12; } finally { if (conn != null) { if (var2 != null) { try { conn.close(); } catch (Throwable var11) { var2.addSuppressed(var11); } } else { conn.close(); } } } } catch (Exception var14) { var14.printStackTrace(); } } }
看吧,原来try-catch-resource就是实质上try-catch-finally加addSuppressed的组合
加入有场景不须要精细判断,而是须要梭哈异常的状况下这个注解能够很方便的帮助你自动生成try-catch,以下代码
import lombok.SneakyThrows; /** * @author wuzt */ public class TryWithResource { @SneakyThrows public static void main(String[] args) { Connection conn = new Connection(); conn.sendData(); } }
使用idea反编译后:
public class TryWithResource { public TryWithResource() { } public static void main(String[] args) { try { Connection conn = new Connection(); conn.sendData(); } catch (Throwable var2) { throw var2; } } }
由上发现,其实这个注解的意义就是抛出全部异常
应用的的场景比较符合的像是阿里开发手册中的以下
求各位看客老爷们点个赞再走啊.