Java中型別擦除與橋接方法
阿新 • • 發佈:2018-12-24
型別擦除與橋接方法
Java中型別擦除與橋接方法
- Java語言是不根據返回值型別來判定是否為方法的過載的
- 方法簽名 = 方法名 + 引數型別
- 但是JVM卻是把返回值型別當做判定條件的
- 方法簽名 = 方法名 + 引數型別 + 返回值型別
可能出現的問題.
- 如果說子類重寫父類方法,返回值型別改變了.對於Java來講是重寫,但是對於JVM卻不是.
- 另外在使用泛型時,父類T,子類重寫父類方法在型別擦除時,方法簽名也會改變.
- 所以在子類重寫父類方法時,如果有上述情況,則會出現橋接方法.
下面,我以型別擦除為例,簡單瞭解一下橋接方法
Node類
package bm;
public class Node<T> {
public T data;
public Node(T data){
this.data = data;
}
public void setData(T data) {
this.data = data;
System.out.println("Node: data = " +data);
}
}
MyNode類
package bm;
public class MyNode extends Node<Integer>{
public MyNode(Integer data) {
super(data);
}
public void setData(Integer data){
System.out.println("Node: data = "+data);
}
}
測試程式碼
public static void main(String[] args) {
MyNode myNode = new MyNode (12);
//原始型別,會有個warning
Node node = myNode;
//型別轉換異常
node.setData("hello");
Integer x = myNode.data;
}
在型別擦除之後,上面的程式碼變成了
public static void main(String[] args) {
MyNode myNode = new MyNode(12);
//原始型別,會有個warning
Node node = (MyNode)myNode;
node.setData("hello");
//型別轉換異常
Integer x = (String)myNode.data;
}
錯誤的原因
- 就是型別轉換錯誤.node引用了myNode
- 雖然呼叫了setData(),但是是父類的.
型別擦除後的兩個類
Node中的泛型引數T 變成了 Object
這樣MyNode就不再是重寫父類的方法了
public class Node {
public Object data;
public Node(Object data) { this.data = data; }
public void setData(Object data) {
this.data = data;
}
}
public class MyNode extends Node {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
super.setData(data);
}
}
為了解決這種情況和維持多型性,所以編譯器就提供了橋接方法(自動生成)
class MyNode extends Node {
// 橋接方法,被編譯器自動生成
public void setData(Object data) {
setData((Integer) data);
}
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
// ...
}