91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解java 中泛型中的類型擦除和橋方法

發布時間:2020-08-24 16:45:43 來源:腳本之家 閱讀:148 作者:lqh 欄目:編程語言

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

       1、  用類型參數(type parameters)的限定(如果沒有就用Object)替換泛型類型中的所有類型參數。

       2、  需要保持類型安全的時候插入類型轉換(隱含插入)

       3、  在extened 泛型類型中生成橋方法來保證多態性

   類型擦除確保不會為已參數化了的類型(paramterized types)產生新類,這樣泛型能保證沒有運行時的負載。

泛型類型擦除

      在類型擦除過程中,java編譯器擦除所有類型參數,用它的限定或者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; } 
 // ... 
} 

因為類型參數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類使用了限定類型參數:

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替換限定參數類型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; } 
 // ... 
} 

同樣,泛型方法也可以擦除。規則類似,不細說。

類型擦除的影響和橋方法

有時候類型擦除會引起無法預知的情況。比如:

給定以下兩個類:

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; // 會引發拋出ClassCastException 

 類型擦除后,代碼變成:

MyNode mn = new MyNode(5); 
Node n = (MyNode)mn;   //原生類型 – 編譯器會給出未檢查警告 
n.setData("Hello"); 
Integer x = (String)mn.data; //會引發拋出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); 
 } 
} 

類型擦除后,方法的簽名已經不匹配。Node 方法變成setData(Object),MyNode方法變成setData(Integer)。MyNode setData方法已經不是覆蓋Node setData方法。

為了解決這個問題,維持泛型類型的多態性,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); 
 } 
 
 // ... 

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福海县| 田林县| 太原市| 曲沃县| 平定县| 黑河市| 清流县| 涟水县| 古交市| 沾益县| 永顺县| 吴江市| 靖远县| 青海省| 梅州市| 肃南| 谢通门县| 平南县| 奉贤区| 蓬安县| 连南| 林口县| 巩义市| 麟游县| 吉木乃县| 青浦区| 东乌珠穆沁旗| 宁南县| 威远县| 武威市| 甘谷县| 盐边县| 清新县| 淮阳县| 余姚市| 九台市| 台中县| 中宁县| 潮安县| 建平县| 吴旗县|