在Java中,泛型的引入是為了在編譯時提供強類型檢查和支持泛型編程。為了實現(xiàn)泛型,Java編譯器應用類型擦除實現(xiàn):

目前創(chuàng)新互聯(lián)已為近1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡空間、網(wǎng)站托管運營、企業(yè)網(wǎng)站設(shè)計、天水網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
1、 用類型參數(shù)(type parameters)的限定(如果沒有就用Object)替換泛型類型中的所有類型參數(shù)。
2、 需要保持類型安全的時候插入類型轉(zhuǎn)換(隱含插入)
3、 在extened 泛型類型中生成橋方法來保證多態(tài)性
類型擦除確保不會為已參數(shù)化了的類型(paramterized types)產(chǎn)生新類,這樣泛型能保證沒有運行時的負載。
泛型類型擦除
在類型擦除過程中,java編譯器擦除所有類型參數(shù),用它的限定或者Object(沒限定時)替換。
考慮下面的泛型類:
public class Node<T> {
private T data;
private Node<T> next;
public Node(T data, Node<T> next) }
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
}
因為類型參數(shù)T是非限定的,Java編譯器使用Object替換它:
public class Node {
private Object data;
private Node next;
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() { return data; }
// ...
}
下面的例子,泛型Node類使用了限定類型參數(shù):
public class Node<T extends Comparable<T>> {
private T data;
private Node<T> next;
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
編譯器會使用第一個限定類,Comparable替換限定參數(shù)類型T:
public class Node {
private Comparable data;
private Node next;
public Node(Comparable data, Node next) {
this.data = data;
this.next = next;
}
public Comparable getData() { return data; }
// ...
}
同樣,泛型方法也可以擦除。規(guī)則類似,不細說。
類型擦除的影響和橋方法
有時候類型擦除會引起無法預知的情況。比如:
給定以下兩個類:
public 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;
}
}
public class MyNode extends Node<Integer> {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
}
考慮以下代碼:
MyNode mn = new MyNode(5);
Node n = mn; // 原生類型 – 編譯器會給出未檢查警告
n.setData("Hello");
Integer x = mn.data; // 會引發(fā)拋出ClassCastException
類型擦除后,代碼變成:
MyNode mn = new MyNode(5);
Node n = (MyNode)mn; //原生類型 – 編譯器會給出未檢查警告
n.setData("Hello");
Integer x = (String)mn.data; //會引發(fā)拋出ClassCastException
public class Node {
public Object data;
public Node(Object data) { this.data = data; }
public void setData(Object data) {
System.out.println("Node.setData");
this.data = data;
}
}
public class MyNode extends Node {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
}
類型擦除后,方法的簽名已經(jīng)不匹配。Node 方法變成setData(Object),MyNode方法變成setData(Integer)。MyNode setData方法已經(jīng)不是覆蓋Node setData方法。
為了解決這個問題,維持泛型類型的多態(tài)性,java編譯器會生成一個橋方法:
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);
}
// ...
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
本文標題:詳解java中泛型中的類型擦除和橋方法
文章地址:http://chinadenli.net/article14/gdjdde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計、網(wǎng)站設(shè)計公司、靜態(tài)網(wǎng)站、關(guān)鍵詞優(yōu)化、建站公司、小程序開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)