根据Java Language Sepecification,第3版:
It is a compile-time error if a generic class is a direct or indirect subclass of
Throwable
.
我想知道为什么会做出这样的决定。泛型异常有什么问题?
(据我所知,泛型只是编译时的语法糖,它们无论如何都会在.class
文件中转换为Object
,因此有效地声明泛型类就好像其中的所有内容都是Object
一样。如果我错了,请纠正我。)
发布于 2009-02-01 18:22:42
正如mark所说的,类型是不可重用的,这在以下情况下是一个问题:
try {
doSomeStuff();
} catch (SomeException<Integer> e) {
// ignore that
} catch (SomeException<String> e) {
crashAndBurn()
}
SomeException<Integer>
和SomeException<String>
都被擦除为同一类型,因此无法区分异常实例,因此也无法判断应该执行哪个catch
块。
发布于 2009-02-01 18:11:05
下面是一个如何使用异常的简单示例:
class IntegerExceptionTest {
public static void main(String[] args) {
try {
throw new IntegerException(42);
} catch (IntegerException e) {
assert e.getValue() == 42;
}
}
}
TRy语句体抛出具有给定值的异常,该异常由catch子句捕获。
相反,禁止使用下面的新异常定义,因为它创建了一个参数化类型:
class ParametricException<T> extends Exception { // compile-time error
private final T value;
public ParametricException(T value) { this.value = value; }
public T getValue() { return value; }
}
尝试编译上述代码时会报告错误:
% javac ParametricException.java
ParametricException.java:1: a generic class may not extend
java.lang.Throwable
class ParametricException<T> extends Exception { // compile-time error
^
1 error
此限制是合理的,因为几乎任何捕获此类异常的尝试都会失败,因为该类型是不可重构的。人们可能会期望异常的典型用法如下所示:
class ParametricExceptionTest {
public static void main(String[] args) {
try {
throw new ParametricException<Integer>(42);
} catch (ParametricException<Integer> e) { // compile-time error
assert e.getValue()==42;
}
}
}
这是不允许的,因为catch子句中的类型是不可重复的。在撰写本文时,Sun编译器在这种情况下报告了一系列语法错误:
% javac ParametricExceptionTest.java
ParametricExceptionTest.java:5: <identifier> expected
} catch (ParametricException<Integer> e) {
^
ParametricExceptionTest.java:8: ')' expected
}
^
ParametricExceptionTest.java:9: '}' expected
}
^
3 errors
因为异常不能是参数化的,所以语法受到限制,因此类型必须写为标识符,不能有以下参数。
发布于 2015-02-09 19:21:21
这本质上是因为它的设计方式很糟糕。
这个问题妨碍了干净的抽象设计,
public interface Repository<ID, E extends Entity<ID>> {
E getById(ID id) throws EntityNotFoundException<E, ID>;
}
catch子句不会因为泛型没有具体化而失败,这不是借口。编译器可以简单地禁止扩展Throwable的具体泛型类型,或者禁止catch子句中的泛型。
https://stackoverflow.com/questions/501277
复制相似问题