Java generics with annotations provides a simple technique for specifying failure policies in an API. The exception in a throws
clause may be a generic parameter. The @Nullable
and @Nonnull
annotations express intent.
In the example, Base
takes an Exception
as a generic parameter. Three implementations demonstrate the choices:
ReturnsNull
is for "finder" type APIs, where anull
return is in good taste.ThrowsUnchecked
is when failure is fatal, and should be handled higher in the stack.ThrowsChecked
is when failure is transient, and can be handled by the caller (e.g., network failures).
Because the exception is defined at a class level, this technique is best for SAM-style APIs or when a common exception is shared by a few calls.
static void main(final String... args) { new ReturnsNull().returnSomething(); System.out.println("Returned null"); try { new ThrowsUnchecked().returnSomething(); } catch (final RuntimeException ignored) { System.out.println("Threw unchecked"); } try { new ThrowsChecked().returnSomething(); } catch (final Exception ignored) { System.out.println("Threw checked"); } } interface Base<E extends Exception> { Object returnSomething() throws E; } final class ReturnsNull implements Base<RuntimeException> { @Nullable @Override public String returnSomething() { return null; } } final class ThrowsUnchecked implements Base<RuntimeException> { @Nonnull @Override public String returnSomething() { throw new RuntimeException(); } } final class ThrowsChecked implements Base<Exception> { @Nonnull @Override public String returnSomething() throws Exception { throw new Exception(); } }
No comments:
Post a Comment