首頁  >  文章  >  Java  >  java類型擦除真的能完全擦除一切資訊嗎?

java類型擦除真的能完全擦除一切資訊嗎?

angryTom
angryTom轉載
2019-11-28 16:20:172061瀏覽

java類型擦除真的能完全擦除一切資訊嗎?

背景:我們都知道泛型本質上是提供類型的"類型參數",它們也被稱為參數化類型(parameterized type)或參量多態性(parametric polymorphism) 。其實泛型思想並不是 Java 最先引入的,C 中的模板就是一個運用泛型的例子。

 (推薦影片:java影片教學#)

GJ(Generic Java)是對Java 語言的一種擴展,是一種帶有參數化類型的Java 語言。用 GJ 寫的程式看起來和普通的 Java 程式基本上相同,只不過多了一些參數化的型別同時少了一些型別轉換。實際上,這些 GJ 程式也是首先被轉換成一般的不帶泛型的 Java 程式後再進行處理的,編譯器自動完成了從 Generic Java 到普通 Java 的翻譯。

类型擦除真的能完全擦除一切信息吗?java 泛型揭秘

 什麼是真實的java泛型

我們都知道編譯器會進行泛型擦除,編譯器可以在對原始程式(帶有泛型的Java 程式碼)進行編譯時使用泛型類型資訊保證類型安全,對大量如果沒有泛型就不會去驗證的類型安全性約束進行驗證,同時在產生的字節碼當中,將這些類型資訊清除掉。 下面我們先驗證一下:

public static void main(String[] args) {
 ArrayList<Integer> ints = new ArrayList<Integer>();
 ints.add(1); 
 ints.add(2);
 ints.add(3);
 ArrayList<String> sts = new ArrayList<String>();
 sts.add("a");
 sts.add("b");
 sts.add("c");
 System.out.println(ints.getClass() == sts.getClass()); 
}

上面印出的結果是true,原因是

##依照理解,泛型擦除後將無法找回原來的類型,都是Object形式的,真的是這樣嗎?

看一下如下程式碼:

import java.lang.reflect.ParameterizedType;import java.util.ArrayList;import java.util.List;public class ClassTest {     
public static void main(String[] args) throws Exception {
     ParameterizedType type = (ParameterizedType) 
     Bar.class.getGenericSuperclass();
     System.out.println(type.getActualTypeArguments()[0]);
     
     ParameterizedType fieldType = (ParameterizedType) 
     Foo.class.getField("children").getGenericType();
     System.out.println(fieldType.getActualTypeArguments()[0]);
     
     ParameterizedType paramType = (ParameterizedType) 
     Foo.class.getMethod("foo", List.class)
     .getGenericParameterTypes()[0];
     System.out.println(paramType.getActualTypeArguments()[0]);
     
     System.out.println(Foo.class.getTypeParameters()[0]
     .getBounds()[0]);
     }     
     class Foo<E extends CharSequence> {     
     public List<Bar> children = new ArrayList<Bar>();     
     public List<StringBuilder> foo(List<String> foo) {return null; }     
     public void bar(List<? extends String> param) {}
     }     
     class Bar extends Foo<String> {}
    }
列印出

class java.lang.Stringclass com.javapuzzle.davidwang456.ClassTest$Barclass java.lang.Stringinterface java.lang.CharSequence
你會發現每個類型參數都被保留了,而且在運行期可以透過反射機制取得。那麼到底什麼是「類型擦除」?至少某些東西被擦除了吧?是的。事實上,除了結構化資訊外的所有東西都被擦除了 —— 這裡結構化資訊是指與類別結構相關的信息,而不是與程式執行流程有關的。換言之,與類別及其欄位和方法的類型參數相關的元資料都會被保留下來,可以透過反射來獲取。

本文來自php中文網,

java教學欄目,歡迎學習!  

以上是java類型擦除真的能完全擦除一切資訊嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除