IOException is being thrown from a method without "throws" declaration, why does this compile?

huangapple 未分类评论46阅读模式
英文:

IOException is being thrown from a method without "throws" declaration, why does this compile?

问题

以下内容在我的平台上编译时没有任何错误。

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) {
    runHello();
  }
}

但是请注意,Example#hello 方法正在从其实现中抛出一个已检查的异常,即 IOException
同时,在主方法的声明中,并没有任何 "throws" 关键字。

实际上,当我运行这个程序时,我会得到以下堆栈跟踪。

$ 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)

它自己抛出了一个 IOException
对我来说,main 方法似乎在运行时违反了其契约(声明),这是不应该发生的。

我的问题是:

  • 为什么这个程序可以编译?在 THE LINE 这一行不应该导致编译错误吗?
  • 如果由于某种原因应该进行编译,那么为什么 main 方法直接抛出 IOException?而不是抛出其他指示正在抛出未声明的异常(类型不匹配)的内容?

我的平台详细信息如下。

$ 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)

提前致谢。

英文:

Following compiles on my platform without any errors.

import java.io.IOException;

public class Example {
  private static final Hello&lt;?&gt; INSTANCE = new Hello&lt;Throwable&gt;() {
    @Override
    public void hello() throws Throwable {
      throw new IOException(&quot;hello&quot;);
    }
  };

  public interface Hello&lt;E extends Throwable&gt; {
    void hello() throws E;
  }

  public static &lt;E extends Throwable&gt; void runHello() throws E {
    ((Hello&lt;E&gt;) INSTANCE).hello();
  }


  public static void main(String... args) {  // NO THROWS DECLARATION
    runHello();  // THE LINE: Shouldn&#39;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 &quot;main&quot; 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 &quot;1.8.0_242&quot;
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.

huangapple
  • 本文由 发表于 2020年4月7日 05:32:08
  • 转载请务必保留本文链接:https://java.coder-hub.com/61069309.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定