在一次使用idea工具進行jdk動態代理方法編寫的時候,出現了一個[rawtypes]的編譯錯誤,見下圖:
經過多次調試和搜集網上的資料,終於發現了問題的原因:
因為jdk動態代理需要傳入一個Class數組,雖然這樣寫Class[] classes = new Class[]{IndexService.class};編輯器不會報錯誤,但是在編譯的時候就會報上面的錯,這是idea的編譯原理導致的,我們需要改成Class<?>[] classes = new Class<?>[]{IndexService.class};就可以順利編譯成功了。
運行完結果正常顯示:
然后在網上查到idea對數組編譯的一些條件限制,在這里列舉出來。
1 class Gen<T> {} 2 3 Gen[] g0 = new Gen[10]; //ok 4 Gen<?>[] g1 = new Gen<?>[10]; //ok 5 Gen<Integer>[] g2 = new Gen[10]; //ok 為什么可以? 6 Gen<Integer>[] g3 = new Gen<Integer>[10]; // error, g2可以,為什么g3不行
我們一句句分析編譯器和 IntelliJ IDEA 的行為。
Gen[] g0 = new Gen[10];
不會出現編譯錯誤和警告,但 IntelliJ IDEA 會對左側的 Gen[]
報 Raw use of parameterized class 'Gen' 警告。
第一句沒有問題,是因為 Java 認為這是 raw use of parameterized type,是兼容 1.5 以前沒有泛型的舊語法。當然,現在不推薦這樣寫,失去了用泛型的意義,不利於類型安全。
Gen<?>[] g1 = new Gen<?>[10];
沒有編譯錯誤和警告,IDEA 也沒有警告。
第二句聲明了 Gen<?>[]
,跟 Gen<Object>[]
基本是一樣的,可以往里面填 Gen<String>
,填Gen<Integer>
等等。這種寫法絕大部分時候都沒有意義,
不如直接用 Gen<Object>[]
。
Gen<Integer>[] g2 = new Gen[10];
沒有編譯錯誤,有編譯警告:
1 Information:java: /C:/Code/TestJava/src/main/java/cnife/Main.java使用了未經檢查或不安全的操作。 2 Information:java: 有關詳細信息, 請使用 -Xlint:unchecked 重新編譯。
同時,IDEA 會對右側的 new Gen[10]
報 Unchecked assignment: 'cnife.Gen[]' to 'cnife.Gen<java.lang.Integer>[]' 警告。
第三句之所以有警告,是因為
Gen<Integer>[]
聲明的變量有類型參數,因此編譯器啟用了類型檢查,這時候再把 raw type 的 Gen[]
賦給變量就會觸發警告,因為編譯器不能保證 Gen[]
里的每個值都是 Gen<Integer>
。 Gen<Integer
>[]
g3 = new Gen<Integer>[10];
有編譯錯誤:
Error:(8, 29) java: 創建泛型數組
IDEA 對 new Gen<Integer>[10]
報 Generic array creation 錯誤。
Gen<String>[]
還是 Gen<Integer>[]
,編譯之后都是 Gen[]
,編譯器不能保證數組里面存的到底是 Gen<String>
還是 Gen<Integer>
,干脆直接禁止創建泛型數組。