Class SneakyThrows
aop package.
Java's checked-exception check is purely a javac constraint - the JVM's bytecode
verifier has no concept of checked versus unchecked, and an athrow instruction can
propagate any Throwable through any frame regardless of that frame's declared
throws clause. sneakyThrow(Throwable) exploits exactly that gap: the generic
bound <E extends Throwable> lets the compiler infer E as an unchecked
RuntimeException at the call site (satisfying the throws-clause check there) while the
erased bytecode throws the original, unmodified Throwable - checked or not.
This is the trade: the compiler's checked-exception analysis is defeated on purpose so a caught
Throwable can cross a generated proxy boundary as its original type instead of being
wrapped or replaced. It exists once, here, for two reverse-direction call sites that both need
it:
ProxyFactory'sInterceptorDispatcher.invokeTrampoline- unwrapsInvocationTargetExceptionso a checked exception the trampoline body throws reaches the interceptor chain as its original type, matching what a directsuper.method()call would have thrownExceptionInterceptor's custom-handler branch - propagates whatever a customExceptionHandler.handleException(java.lang.Throwable, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])deliberately re-throws, including a checkedThrowablethe intercepted method's ownthrowsclause does not declare
ProxyFactory's InterceptorDispatcher so both
call sites share one implementation - a second, independently-maintained copy is the exact class
of defect this milestone exists to close (one rule, implemented twice, silently diverging).- Since:
- 6.3.0
- Author:
- wisdomme
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) static <E extends Throwable>
RuntimeExceptionRethrowstunmodified, bypassing the compiler's checked-exception check.
-
Constructor Details
-
SneakyThrows
private SneakyThrows()
-
-
Method Details
-
sneakyThrow
Rethrowstunmodified, bypassing the compiler's checked-exception check.Callers write
throw SneakyThrows.sneakyThrow(t);so a method whose ownthrowsclause does not (and, for an override, cannot) declaret's checked type still compiles - the declaredRuntimeExceptionreturn type never actually returns, since the generic-cast trick always throws.- Type Parameters:
E- inferred as an unchecked type at the call site sojavacpermits the throw- Parameters:
t- the throwable to rethrow, exactly as given- Returns:
- never returns; declared as
RuntimeExceptiononly to satisfy the compiler at call sites that want to writethrow sneakyThrow(t);as a single statement - Throws:
E- always - the actual runtime type ist's own class, checked or not
-