相关疑难解决方法(0)

为什么Java不允许Throwable的泛型子类?

根据Java语言规范,第3版:

如果泛型类是其直接或间接子类,则为编译时错误Throwable.

我希望理解为什么做出这个决定.通用异常有什么问题?

(据我所知,泛型只是编译时的语法糖,他们将被翻译成Object反正在.class文件,因此有效地声明一个泛型类是仿佛一切都在它是一个Object,请纠正我,如果我错了.)

java generics language-design exception

142
推荐指数
4
解决办法
3万
查看次数

为什么Java 8类型推断不考虑Lambdas在重载选择中引发的异常?

关于lambdas及其相关的异常签名,我有一个关于Java 8推断的问题.

如果我定义一些方法foo:

public static <T> void foo(Supplier<T> supplier) {
    //some logic
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,我得到了foo(() -> getTheT());在大多数情况下能够为给定的内容编写的漂亮而简洁的语义T.但是,在此示例中,如果我的getTheT操作声明了它throws Exception,我的foo方法使得供应商不再编译:供应商方法签名get不会抛出异常.

这似乎是解决这个问题的一个不错的方法是重载foo以接受任一选项,重载定义为:

public static <T> void foo(ThrowingSupplier<T> supplier) {
   //same logic as other one
   ...
}
Run Code Online (Sandbox Code Playgroud)

其中ThrowingSupplier定义为

public interface ThrowingSupplier<T> {
   public T get() throws Exception;
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,我们有一个引发异常的供应商类型和一个不引发异常的供应商类型.所需的语法将是这样的:

foo(() -> operationWhichDoesntThrow()); //Doesn't throw, handled by Supplier
foo(() -> operationWhichThrows()); //Does throw, handled by ThrowingSupplier
Run Code Online (Sandbox Code Playgroud)

但是,这会导致问题,因为lambda类型不明确(可能无法在Supplier和ThrowingSupplier之间解决).做一个明确的演员foo((ThrowingSupplier)(() -> operationWhichThrows()));可以工作,但它摆脱了所需语法的大部分简洁性.

我想基本的问题是:如果Java编译器能够解决我的一个lambdas由于它在仅供应商案例中抛出异常而不兼容的事实,为什么它不能使用相同的信息来导出二级,类型推理案例中lambda的类型?

任何人都可以指出的任何信息或资源同样值得赞赏,因为我不太确定在哪里可以找到有关此事的更多信息. …

java lambda type-inference exception java-8

40
推荐指数
2
解决办法
1470
查看次数