Whi*_*cal 1 java generics types casting exception
我有这个演示,我不需要一个具有重绘架构的特定解决方案,但只是理解为什么这样做以及我为避免它而遗漏的任何事情.我想知道为什么:
当我们尝试获取元素而不是推送它时抛出ClassCast异常
import Test.*; //Inner classes
import java.util.List;
import java.util.ArrayList;
public class Test<E extends Object> {
private List<E> list = new ArrayList<E>();
public Test() {}
public static void main(String[] args) {
Test<String> a = new Test<String>();
a.addElement(new String());
a.addElement(new Integer(0)); // No complain in comp/run-time, I dont understand why CastException is not thrown here
String class1 = a.getElement(0);
String class2 = a.getElement(1); //No complain in comp but ClassCastException: Integer cannot be cast to String
//Integer class3 = a.getElement(1); //Compilation error
}
public void addElement (Object node) { list.add((E) node); } //No complain in comp/run-time
public E getElement(int index) { return list.get(index); }
}
Run Code Online (Sandbox Code Playgroud)什么可以解决方案?注意我需要传递SuperClass而不是类型E的addElement行.这是我的架构所需要的,这只是一个简单的模拟演示.但无论如何,类型E的转换应按预期运行并在运行时抛出CastExeption,不应该?
您的addElement方法没有正确使用泛型来允许编译时错误捕获.它应该是:
public void addElement(E node) {
list.add(node);
}
Run Code Online (Sandbox Code Playgroud)
一旦使用Object强制转换并将其强制转换为E,就会失去编译时类型检查的好处.这就是为什么我们首先使用泛型,以避免使用Object变量并避免强制转换.
请注意,在运行时,由于泛型类型擦除,List只是一个对象列表,因此当您将对象放入列表时,第一次转换甚至不会发生.但是当你从列表中提取项目并需要将它分配给具体的类型变量时,会发生场景转换,这会导致抛出异常.