vendredi 2 août 2019

Why does a java.lang.reflect.Proxy require declaring checked exceptions when normal method invocation does not?

Java's Proxy requires that any checked exceptions thrown from the backing InvocationHandler are declared on the interface method that is currently being invoked.

For example, given a test interface,

interface Foo {
  void bar1();
  void bar2() throws IOException;
}

An Proxy-based instance backed by an InvocationHandler that always throws IOException produces two behaviors:

  • bar1() will throw an unchecked UndeclaredThrowableException with the IOException as its cause.
  • bar2() will throw the IOException directly.

Now, implement this interface with a normal class and throw IOException from both methods¹. Callers to either method will receive the IOException thrown directly.

Why does a Proxy enforce checked exceptions at runtime when seemingly no other part of the VM does?


Note: this case is distinctly different than methods which are forced to wrap checked exceptions in order to throw them which is commonly seen in patterns like

} catch (e: IOException) {
  throw new UncheckedIOException(e);
}

¹ Either by using the "sneaky throw" technique, writing it in a language without checked exceptions like Kotlin, or implementing the class directly in bytecode.





Aucun commentaire:

Enregistrer un commentaire