We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.
I guess I didn't put too much thought into how lombok might've achieved what they do with @SneakyThrows and now I know :)
Thank you
Oh, I just noticed that for some reason the generics display in a weird manner in the bigger snippet.
Just in case, where it says `x extends="" throwable=""`
It should actually say `X extends Throwable`.
For some reason I can't fix it - when I'm editing the message, it displays properly
I would add 2-3 points.
About "I don’t know what Lombok is doing to make compiler happy".
What Lombok does can easily be done with vanilla Java.
@SuppressWarnings("unchecked")
public static <x extends="" throwable="">
void sneakyThrow(Exception e) throws X {
throw (X) e;
}
public static void main(String[] args) {
sneakyThrow(new IOException("Heh")); // works without `throws IOException`, without any wrapping
}
// or something that is easier to use in code
// because it allows to `return sneakyThrow(...);`
// instead of `sneakyThrow(...); return null;`
@SuppressWarnings("unchecked")
public static <r, x="" extends="" throwable="">
R sneakyThrow(Exception e) throws X {
throw (X) e;
}
public static void main(String[] args) {
Integer i = sneakyThrow(new IOException("Heh"));
}
And with that in mind, the changes in behavior happen not because of Lombok, but because of how proxies are implemented.
But you already explained that in the article, pointing out what happens with the JDK proxy example.
Anyway, a sneaky throw, be it via Lombok, or vanilla java, is like a nuclear weapon that says "I don't intend to handle this exception, and I don't give you a chance neither. " or "This method doesn't throw anything checked, trust me".
According to Lombok docs, it has only 2 use-cases:
1 - When one is 100% sure the exception will never be thrown.
2 - When one has no other recovery strategy, other than aborting everything and hoping it will be logged somewhere up with some
(catch Exception). That is, the only way to catch such an exception is viacatch (Exception e)and maybe some instanceof checks.Sneaky throw don't disable the "checking" aspect. When one uses sneaky throw, instead of throws, he declares "this method doesn't throw it", so nobody can `catch` it by the proper type.
Rolling back a transaction is neither of those 2 use-cases.
My last point would be, that Lombok's `@SneakyThrows` also takes a list of exception classes.
If I ever use SneakyThrows, I always list the exact exceptions that I'm ignoring, and often attach a comment explaining the rationale behind that.
And because of the "this method doesn't throw X" semantics, I personally only use it for the 1st use-case, where I'm sure an exception is never thrown.