lombok注释@SneakyThrows

青松周*_*青松周 3 java lombok

我有一个关于@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()源代码,你会发现它最终做了两件事:

  1. 空检查
  2. 演员阵容

两者都作为编译的一部分被删除,这就是为什么您的反编译代码只是重新抛出异常。


use*_*900 6

请参阅@SneakyThrows,它使用Lombok.sneakyThrow(t)而不是var2:

public void run() {
    try {
      throw new Throwable();
    } catch (Throwable t) {
      throw Lombok.sneakyThrow(t);
    }
  }
Run Code Online (Sandbox Code Playgroud)