为什么Java不支持通用的可抛出物?

2022-09-01 20:32:32
class Bouncy<T> extends Throwable {     
}
// Error: the generic class Bouncy<T> may not subclass java.lang.Throwable

为什么 Java 不支持泛型 s?Throwable

我意识到类型擦除使某些事情复杂化,但显然Java已经做了很多事情,所以为什么不把它再推一个档次,并允许泛型s,并全面编译时检查潜在的问题呢?Throwable


我觉得类型擦除的论点相当薄弱。目前,我们无法执行以下操作:

void process(List<String> list) {
}

void process(List<Integer> list) {
}

当然,我们没有它也能过得去。我并不是要求我们应该能够在同一个块中做到这一点,但是如果我们在具有严格的编译时可执行规则的不相交上下文中使用它们(这几乎是泛型现在的工作方式),那么它难道不可行吗?catch Bouncy<T1>Bouncy<T2>try


答案 1

Java 语言规范 8.1.2 泛型类和类型参数

此限制是必需的,因为 Java 虚拟机的 catch 机制仅适用于非泛型类。

就个人而言,我认为这是因为我们无法在子句中获得泛型的任何好处。由于类型擦除,我们无法编写,但是如果我们编写 ,则将其通用化是无用的。catchcatch (Bouncy<String> ex)catch (Bouncy ex)


答案 2

简短的回答:因为他们走捷径,就像他们删除一样。

很长的答案:正如其他人已经指出的那样,由于擦除,没有办法在运行时区分“catch MyException<String>”和“catch MyException<Integer>”。

但这并不意味着不需要通用例外。我希望泛型能够使用泛型字段!他们可以简单地允许通用异常,但只允许在原始状态下捕获它们(例如,“捕获MyException”)。

当然,这将使泛型更加复杂。这是为了表明删除泛型的决定有多糟糕。我们什么时候会有一个Java版本支持真正的泛型(使用RTTI),而不是当前的语法糖?