英文:
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<?> 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.
专注分享java语言的经验与见解,让所有开发者获益!
评论