导读:@SneakyThrows注解是由lombok为我们封装的,它可以为我们的代码生成一个try...catch块,并把异常向上抛出来,而你之前的ex.getStackTrace()是没有这种能力的,有时,我们从底层抛出的异常需要被上层统一收集,而又不想在底层new出一大堆业务相关的异常实例,这时使用@SneakyThrows可以简化我们的代码。
@SneakyThrows可以用来偷偷抛出已检查的异常而不在方法的throws子句中实际声明这一点。当然,应该谨慎使用这种有争议的能力。由lombok生成的代码不会忽略,包装,替换或以其他方式修改抛出的已检查异常; 它只是伪造了编译器。在JVM(类文件)级别,无论方法的throws子句如何,都可以抛出所有异常,无论是否检查,这就是为什么这样做的原因。
当您想要选择退出已检查的异常机制时,常见的用例围绕两种情况:
前者会强制要求抛出它的方法声明throws,调用者必须显示的去处理这个异常。设计的目的是为了提醒开发者处理一些场景中必然可能存在的异常情况。比如网络异常造成IOException。
但是现实,往往事与愿违。大部分情况下的异常,我们都是一路往外抛了事。(强制处理我也处理不了啊!臣妾做不到)所以渐渐的java程序员处理Exception的常见手段就是外面包一层RuntimeException,接着往上丢。这种解决思想尤其在Spring中到处出现。参见《Spring in Action》
Lombok的@SneakyThrows就是为了消除这样的模板代码。
案例分享
真正生成的代码
显然魔法 藏在Lombok.sneakyThrow(t);中。可能大家都会以为这个方法就是new RuntimeException()之类的。
然而事实并非如此,阅读代码可以看出整个方法其实最核心的逻辑是throw (T)t;,利用泛型将我们传入的Throwable强转为RuntimeException。虽然事实上我们不是RuntimeException。但是没关系,因为JVM并不关心这个。泛型最后存储为字节码时并没有泛型的信息。这样写只是为了骗过javac编译器,源码中注释有解释。
- END -