神奇的互換身體術--java的類型擦除


故事背景

《互換身體》是由環球影業發行的喜劇電影,於2011年8月5日在美國上映。該片由大衛·道金執導,瑞安·雷諾茲、傑森·貝特曼、奧利維亞·王爾德等主演。該片講述了一位居家好男人和一位蜂蝶浪子分別厭倦了自己的生活,於是在某種神秘力量的輔助下兩人互換身體與生活的故事。

神奇的互換身體術--java的類型擦除

 

大話西游:紫霞和八戒互換了身體,欲和至尊寶親熱,結果直接吐了

神奇的互換身體術--java的類型擦除

 

java的換身術

java中也可以實現神奇的魔法,比如把String放入List<Integer>或者把Integer放入List<String>.請看:

public static void main(String[] args) {
 ArrayList<Integer> list = new ArrayList<Integer>();
 list.add(1); 
 list.add(2);
 list.add(3);
 try {
            list.getClass().getMethod("add", Object.class).invoke(list, "www");
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
                | SecurityException e) {
            e.printStackTrace();
        }
 for (int i = 0; i < list.size(); i++) {
 System.out.println(list.get(i));
 }
 }

打印出的結果為:

1
2
3
www
神奇的互換身體術--java的類型擦除

 

震驚了嗎? 整數的list里面竟然有字符串!!!

類型的限定是不是沒有其作用?不信的話,繼續看:

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

神奇的互換身體術--java的類型擦除

 

原來是類型擦除惹的禍。

類型擦除

當編譯器對帶有泛型的 Java 代碼進行編譯時,它會去執行類型檢查和類型推斷,然后生成普通的不帶泛型的字節碼,這種字節碼可以被一般的 Java 虛擬機接收並執行,這種技術被稱為擦除(erasure)。

因為種種原因,Java不能實現真正的泛型,只能使用類型擦除來實現偽泛型,這樣雖然不會有類型膨脹問題,但是也引起來許多新問題,所以,SUN對這些問題做出了種種限制,避免我們發生各種錯誤。

編譯器可以在對源程序(帶有泛型的 Java 代碼)進行編譯時使用泛型類型信息保證類型安全,對大量如果沒有泛型就不會去驗證的類型安全約束進行驗證,同時在生成的字節碼當中,將這些類型信息清除掉。

Java 中的泛型與 C++ 模板的比較

GJ(Generic Java)程序的語法在表面上與 C++ 中的模板非常類似,但是二者之間有着本質的區別。

首先,Java 語言中的泛型不能接受基本類型作為類型參數――它只能接受引用類型。這意味着可以定義 List<Integer>,但是不可以定義 List<int>。

其次,在 C++ 模板中,編譯器使用提供的類型參數來擴充模板,因此,為 List<A> 生成的 C++ 代碼不同於為 List<B> 生成的代碼,List<A> 和 List<B> 實際上是兩個不同的類。而 Java 中的泛型則以不同的方式實現,編譯器僅僅對這些類型參數進行擦除和替換。類型 ArrayList<Integer> 和 ArrayList<String> 的對象共享相同的類,並且只存在一個 ArrayList 類。

參考資料

【1】https://baike.baidu.com/item/%E4%BA%92%E6%8D%A2%E8%BA%AB%E4%BD%93/510590?fr=aladdin

【2】https://www.cnblogs.com/wuqinglong/p/9456193.html

【3】https://www.ibm.com/developerworks/cn/java/j-lo-gj/?mhsrc=ibmsearch_a&mhq=%E7%B1%BB%E5%9E%8B%E6%93%A6%E9%99%A4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM