我正在学习关于泛型的Java教程,并以我自己的方式在http://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html上玩这个例子。
两个班级:
public class Node<T> {
private T data;
public Node(T data) {
this.data = data;
}
public void setData(T data) {
this.data = data;
}
}
public class MyNode extends Node<Integer> {
public MyNode(Integer data) {
super(data);
}
public void setData(Integer data) {
super.setData(data);
}
}
由于类型擦除,下面的代码将编译:
MyNode mn = new MyNode(5); // 1
Node n = mn; // 2
n.setData("Hello"); // 3
因为第3行实际上是调用类型擦除方法Node.setData(Object)。但是会抛出运行时ClassCastException
。
以下是我的实验:我打印出字段data
的类型。 Node和MyNode中都是Object
。
以下是我的问题:
节点具有Object
类型,由于类型擦除而没有任何意外。但是,为什么MyNode还有Object
类型的数据&#34;数据&#34;?
如果MyNode&#34;数据&#34;具有Object
类型,运行时类型检查如何工作? (ClassCastException
异常......)在我看来,MyNode中的数据类型也已被删除(我的拼图#1)。
Java版:HotSpot 1.8.0_05-b13
答案 0 :(得分:2)
这与Generics
或Type Erasure
无关。
您告诉编译器Node n
并且没有提供任何类型,因此它将需要任何内容。
这与将ArrayList<String>
向下转换为List
并抱怨任何抱怨并没有什么不同。
final List los = new ArrayList<String>();
los.add(new Date());
los.add(1);
这是明确定义和预期的行为,它正在做你要告诉它的事情。
答案 1 :(得分:2)
我打印出了字段数据的类型
你打印出来的是一种名为“data”的refence类型。确实设置为Object
。
但是为什么MyNode也有“数据”的对象类型?
不确定您正在谈论哪些数据。局部变量data
的引用类型将为Integer
,而属性引用类型为Object
如果MyNode的“数据”具有Object类型,运行时类型检查如何工作? (ClassCastException异常......)在我看来,MyNode中的数据类型也被删除了(我的拼图#1)。
执行此操作时:
public void setData(Integer data) {
super.setData(data);
}
Java编译器只需将其转换为:
public void setData(Object arg) {
Integer data = (Integer) arg;
//Now you can use "data" refenrence with proper type
super.setData(data);
}
这是ClassCastException的来源。