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:
ReturnsNullis for "finder" type APIs, where anullreturn is in good taste.ThrowsUncheckedis when failure is fatal, and should be handled higher in the stack.ThrowsCheckedis 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