我们知道,java里的异常分为Exception和RuntimeException两大类,RuntimeException异常会由运行时帮我们进行捕获,统一进行处理;而Exception异常是受检异常(Checked Exception),需要我们自己在代码里显示的声明和处理。
RuntimeException异常的代表
- llegalArgumentException
- IllegalAnnotationException
- EncodingException
Exception的代表
- IOException
- IllegalBlockSizeException
- GeneralSecurityException
- IllegalAccessException
问题表现
在一个类中,定义两个方法a和b,b方法会声明throws IOException,a方法里面在调用b方法里,也需要对这个IOException进行处理,这时IDE会提升我们,需要显示的实现这个异常的捕获。
如下面和图所示,你有三种选择,添加throws,添加lombok @SneakyThrows注解,以及添加try...catch等
第一种,代码变成这样
public void a() throws IOException {
b();
}
第二种,代码变成这样
@SneakyThrows
public void a() {
b();
}
第三种,代码就是传统的try...catch了
public void a() {
try {
b();
} catch (IOException e) {
e.printStackTrace();
}
}
从上面三段代码来说,无疑lombok封装的@SneakyThrows代码最为简洁,添加它之后,IDE的警告就没有了,它实际是把Exception伪装成了RuntimeException,把JVM给欺骗了。
下面代码选自sneakyThrow的实现,它将我们的异常强转成了RuntimeException异常,编译器一看它不是Exception异常,所以警告信息也就没了。
public static RuntimeException sneakyThrow(Throwable t) {
if (t == null) throw new NullPointerException("t");
return Lombok.<RuntimeException>sneakyThrow0(t);
}
private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T {
throw (T)t;
}