[英]Erasure type and Bridging Method clarification
以下代码取自 Oracle 泛型文档 -
class Node<T> {
public T data;
public Node(T data) { this.data = data; }
public void setData(T data) {
System.out.println("Node.setData");
this.data = data;
}
}
class MyNode extends Node<Integer> {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
public static void main(String[] args) {
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = mn.data; // Causes a ClassCastException to be thrown.
}
}
我对这段代码的理解 -
问 - 方法setData
覆盖或重载?
我的MyNode
- 因为MyNode
正在扩展Node<Integer>
,所以类型参数T
值设置为Integer
。
所以类Node
有方法setData(Integer data)
作为 T= Integer 和类MyNode
有方法setData(Integer data)
。
因为签名是一样的,所以它是压倒性的。
问-即使在擦除之后,setData 方法是否被覆盖? 我的理解 -
在我们擦除<T>
之后, Node
的 set 方法变成了setData(Object data)
Mynode
的 set 方法将是 - setData(Integer data)
因为没有类型参数,没有要删除的内容。
但这是重载。
问 - 我们想要重载还是覆盖?
我的理解 - 根据擦除之前定义的方法的外观,我们想要覆盖.
问 - 那么如何实现擦除后覆盖?
我的理解 - 通过桥接方法。 例如:
setData(Object data){
setData((Integer) Data);
}
我的理解正确吗?
此外, class MyNode extends Node<Integer>
什么时候Integer
被向下传递到<T>
什么时候调用 super ?
setData
被覆盖了。 从用户的角度来看,它看起来好像setData(T data)
被setData(Integer i)
覆盖,即当你调用setData(42)
,它会用"MyNode"打印一些东西,而不是用"Node ” 。
在类型擦除方法签名的级别上,这将通过添加到MyNode
的合成桥方法setData(Object)
来实现,即如果您使用javap
反编译MyNode.class
,您将看到两个方法:
public void setData(java.lang.Integer); public void setData(java.lang.Object);
语言规范说"override" ,我不知道为什么有人会想要别的东西。
不清楚您所说的“擦除后实现覆盖”是什么意思。 类型擦除是在类型检查和确定什么覆盖什么之后进行的。 没有什么可以“实现”的,它只是事物工作的顺序(另请参阅此评论)。 覆盖原始setData(Object)
的合成桥接方法看起来像你写的(最多有轻微的错别字):
setData(Object data){ setData((Integer) data); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.