[英]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.