在为这个站点编写另一个答案的代码时,我遇到了这个奇怪的问题:
static void testSneaky() {
final Exception e = new Exception();
sneakyThrow(e); //no problems here
nonSneakyThrow(e); //ERRROR: Unhandled exception: java.lang.Exception
}
@SuppressWarnings("unchecked")
static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
throw (T) t;
}
static <T extends Throwable> void nonSneakyThrow(T t) throws T {
throw t;
}
首先,我非常困惑为什么编译器认为sneakyThrow
调用是可以的。当没有任何未经检查异常类型的提及时,它可能为T
推断了什么样的类型呢?
其次,假设这是可行的,那么为什么编译器会抱怨nonSneakyThrow
调用呢?它们看起来非常相似。
sneakyThrow
调用。有关throws T
形式推断的特殊规定在Java 7的规范中并不存在。 - Marko TopolniknonSneakyThrow
中,T
必须是Exception
,而不是Exception
的"一个超类型",因为它恰好是在调用时声明的参数的类型。 - llogiqException
,上限是Throwable
,因此最小上界(即推断出的结果类型)是Exception
。 - thecoopException
itself”这个短语可能对读者有所帮助,但一般来说,应该注意规范总是在“包括自身”的意义上使用“子类型”和“超类型”这些术语... - Holger