3

Following compiles on my platform without any errors.

import java.io.IOException;

public class Example {
  private static final Hello<?> INSTANCE = new Hello<Throwable>() {
    @Override
    public void hello() throws Throwable {
      throw new IOException("hello");
    }
  };

  public interface Hello<E extends Throwable> {
    void hello() throws E;
  }

  public static <E extends Throwable> void runHello() throws E {
    ((Hello<E>) INSTANCE).hello();
  }


  public static void main(String... args) {  // NO THROWS DECLARATION
    runHello();  // THE LINE: Shouldn't this be complained by the compiler?
  }
}

But look, the Example#hello method is throwing an IOException, which is a checked exception, from its implementation. And at the same time in the declaration of the main method, it doesn't have any "throws".

As a matter of fact, when I run this, I get a following stack trace.

$ java -cp target/test-classes com.github.dakusui.pcond.ut.providers.Example
Exception in thread "main" java.io.IOException: hello
        at com.github.dakusui.pcond.ut.providers.Example$1.hello(Example.java:9)
        at com.github.dakusui.pcond.ut.providers.Example.runHello(Example.java:18)
        at com.github.dakusui.pcond.ut.providers.Example.main(Example.java:23)

It is throwing an IOException itself. To me the main method seems to violate its contract (declaration) at runtime, which must not happen.

My questions are

  • Why can this program be compiled? Shouldn't it result in a compilation error at THE LINE?
  • If it should be compiled for some reason, then why the main method throws IOException directly. Instead of something else that indicates an undeclared exception (type mismatch) is being thrown?

The detail of my platform is following.

$ java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-8u242-b08-0ubuntu3~18.04-b08)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

Thanks in advance.

Hiroshi_U
  • 61
  • 6
  • 2
    Does this answer your question? [Java SneakyThrow of exceptions, type erasure](https://stackoverflow.com/questions/14038649/java-sneakythrow-of-exceptions-type-erasure) – IlyaMuravjov Apr 06 '20 at 22:35
  • Thanks @Bananon. It at lest partially answered my question but it makes me think even more. In my code the upperbound is Throwable, which the compiler should know. Even if it's raw, still it throws something. For the compiler there is no clue to determine that it is an exception which does not require 'throws'. In that case, it would have been possible to design the language so that it assumes the method is throwing Throwable and results in a compilation error. Why didn't they take this approach? – Hiroshi_U Apr 07 '20 at 04:13

0 Answers0