我有一个关于@SneakyThrows的问题可以用来偷偷抛出已检查的异常而不在你的方法的throws子句中实际声明这一点.
public class Demo {
public static void main(String[] args) {
}
private void throwE() throws ClassNotFoundException {
}
@SneakyThrows
private void t() {
throwE();
}
}
Run Code Online (Sandbox Code Playgroud)
这是由lombok生成的.
public class Demo {
public Demo() {
}
public static void main(String[] args) throws IOException {
}
private void throwE() throws ClassNotFoundException {
}
private void t() {
try {
this.throwE();
} catch (Throwable var2) {
throw var2;
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么lombok生成的代码可以在不声明throws子句的情况下伪造编译器.
小智 8
答案是 Lombok 欺骗了编译器 - 但您所显示的是已编译字节代码的反编译版本 - 并且运行字节代码的 JVM 不区分已检查和未检查的异常:它不在乎。
如果你看一下Lombok.sneakyThrow()
源代码,你会发现它最终做了两件事:
两者都作为编译的一部分被删除,这就是为什么您的反编译代码只是重新抛出异常。
请参阅@SneakyThrows,它使用Lombok.sneakyThrow(t)
而不是var2
:
Run Code Online (Sandbox Code Playgroud)public void run() { try { throw new Throwable(); } catch (Throwable t) { throw Lombok.sneakyThrow(t); } }