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.

2
  • 2
    Does this answer your question? Java SneakyThrow of exceptions, type erasure Commented Apr 6, 2020 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? Commented Apr 7, 2020 at 4:13

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.