Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lombok annotation @SneakyThrows

Tags:

java

lombok

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.

like image 446
青松周 Avatar asked Nov 21 '18 12:11

青松周


People also ask

What does a checked exception mean?

A checked exception is a type of exception that must be either caught or declared in the method in which it is thrown. For example, the java.io.IOException is a checked exception.

Can we use throw without throws Java?

Without using throwsWhen an exception is cached in a catch block, you can re-throw it using the throw keyword (which is used to throw the exception objects). If you re-throw the exception, just like in the case of throws clause this exception now, will be generated at in the method that calls the current one.

Can we use throws at class level?

You can by throw exception at constructor level.

What is checked and unchecked exception?

A checked exception must be handled either by re-throwing or with a try catch block, a runtime isn't required to be handled. An unchecked exception is a programming error and are fatal, whereas a checked exception is an exception condition within your codes logic and can be recovered or retried from.


2 Answers

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.

like image 171
Kunda Avatar answered Oct 21 '22 01:10

Kunda


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

public void run() {
    try {
      throw new Throwable();
    } catch (Throwable t) {
      throw Lombok.sneakyThrow(t);
    }
  }
like image 21
user7294900 Avatar answered Oct 21 '22 03:10

user7294900