程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> 泛型-對於Java反射的安全性的一些疑問

泛型-對於Java反射的安全性的一些疑問

編輯:編程綜合問答
對於Java反射的安全性的一些疑問

最近在看深入理解JVM,隨手寫了一點代碼,有個問題不太理解。
代碼如下:

    public static void main(String[] args) throws Exception {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        Method put = HashMap.class.getMethod("put", Object.class, Object.class);
        put.invoke(map, 1, new Object());
        System.out.println(map);
        String val = map.get(1);
        System.out.println(val);
    }

執行結果(編譯和執行版本都是1.6):

 {1=java.lang.Object@2e6e1408}
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
    at T002.main(T002.java:12)

報錯是在String val = map.get(1);這一行。

我不解的是:
通過反射,Integer-Object鍵值對竟然正確地放進了Integer-String的HashMap中!

這種不合理的結果,應當是很嚴重的BUG了吧,但是也從沒聽誰提到過。

希望大家多多指點

最佳回答:


另外java泛型的機制:
http://irfen.iteye.com/blog/1888312

Java泛型實現原理:類型擦出
       Java的泛型是偽泛型。在編譯期間,所有的泛型信息都會被擦除掉。正確理解泛型概念的首要前提是理解類型擦出(type erasure)。
       Java中的泛型基本上都是在編譯器這個層次來實現的。在生成的Java字節碼中是不包含泛型中的類型信息的。使用泛型的時候加上的類型參數,會在編譯器在編譯的時候去掉。這個過程就稱為類型擦除。
    如在代碼中定義的List<object>和List<String>等類型,在編譯後都會編程List。JVM看到的只是List,而由泛型附加的類型信息對JVM來說是不可見的。Java編譯器會在編譯時盡可能的發現可能出錯的地方,但是仍然無法避免在運行時刻出現類型轉換異常的情況。類型擦除也是Java的泛型實現方法與C++模版機制實現方式(後面介紹)之間的重要區別。 

因為是編譯完成的,包括類型檢查這些,而反射繞過了編譯檢查,所以是沒辦法的。

yizishou
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved