我有以下课程(简化但仍然是一个有效的示例):
class Test<T> {
List<T> l = new ArrayList<>();
public Test() {
}
public void add(Object o) {
l.add((T)o);
}
}
以及测试代码:
Test<Double> t = new Test<>();
t.add(1);
t.add(1.2);
t.add(-5.6e-2);
t.add("hello");
一切都很顺利,但这不是我所期望的。不应该是add
方法抛出一个ClassCastException
?如果我添加一个get
方法或多或少是相同的:
public T get(int i) {
return l.get(i);
}
.../...
t.get(1); // OK.
t.get(3); // OK (?)
Double d = t.get(3); // throws ClassCastException
为什么只有在变量赋值时才会抛出异常?如果(T)
演员阵容不起作用?
add 方法不应该抛出一个ClassCastException
?
不,不应该(尽管我希望如此)。长话短说,泛型的 Java 实现在编译代码后会丢弃类型信息,因此List<T>
允许采取任何Object
,以及你的演员阵容add
方法没有被检查。
为什么只有在变量赋值时才会抛出异常?
因为演员阵容Double
由编译器插入。 Java 编译器知道返回类型get
is T
,即Double
,因此它插入一个强制转换以匹配变量的类型d
,结果被分配给它。
以下是实现泛型安全转换的方法:
class Test<T> {
private final Class<T> cl;
List<T> l = new ArrayList<>();
public Test(Class<T> c) {
cl = c;
}
public void add(Object o) {
l.add(cl.cast(o));
}
}
现在演员阵容由Class<T>
对象,所以你会得到一个ClassCastException
尝试插入错误类型的对象。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)