11

I have question about @SneakyThrows can be used to sneakily throw checked exceptions without actually declaring this in your method's throws clause.

public class Demo {

    public static void main(String[] args) {

    }

    private void throwE() throws ClassNotFoundException {

    }

    @SneakyThrows
    private void t() {
        throwE();
    }
}

Here is generate by 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;
        }
    }
}

Why the code generate by lombok can fakes out the compiler without declaring throws clause.

青松周
  • 163
  • 1
  • 1
  • 5

2 Answers2

8

See @SneakyThrows, it uses Lombok.sneakyThrow(t) and not var2:

public void run() {
    try {
      throw new Throwable();
    } catch (Throwable t) {
      throw Lombok.sneakyThrow(t);
    }
  }
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • Thanks for your reply. The code `throw var2` is decompile by devtool and i believe it's generate lombok plugin.Obviously it's different from code `throw Lombok.sneakyThrow(t)`. – 青松周 Nov 21 '18 at 14:06
8

The answer is that Lombok cheats the compiler - but what you've shown is a decompiled version of the compiled byte code - and the JVM running the byte code does not distinguish between checked and unchecked exceptions: it does not care.

If you take a look at Lombok.sneakyThrow() source code, you'll see that it eventually does two things:

  1. A null check
  2. A cast

Both are removed as part of the compilation, which is why your decompiled code simply rethrows the exception.

Kunda
  • 463
  • 3
  • 5