2013-10-08 126 views
9

使用泛型時我發現了一個奇怪的行爲。原始類型成員丟失的泛型類型

在這個類Foo<T>,在strings成員沒有任何與T

package test; 
import java.util.ArrayList; 

public class Foo<T> { 
    ArrayList<String> strings; 

    T getSome() { 
     return null; 
    } 
} 

類是主要用於:

package test; 

public class Main { 

    public static void main() { 
     Foo<Integer> intFoo = new Foo<>(); 
     Integer i = intFoo.getSome(); 
     String s1 = intFoo.strings.get(0); 

     Foo rawFoo = new Foo(); 
     Object o = rawFoo.getSome(); 
     String s2 = rawFoo.strings.get(0); // Compilation error on this line 
    } 
} 

的編譯錯誤是「不兼容的類型。required:String found:Object「。

當使用原始類型Foo時,Java似乎忘記了String類型參數爲ArrayList

我的Java版本爲1.7.0_21

+7

這是完全正常的。原始類型完全是原始的(所有成員)。請搜索類似的問題。 –

+2

原始類型是爲了向後兼容。從[原始類型的java教程](http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html):「使用原始類型時,您基本上會獲得預先泛型行爲」。如果Foo的原始類型具有通用成員(即使它不依賴於T),它將不會向後兼容 –

回答

10

簡單地說,因爲rawFoo是原料,它的非靜態成員也成爲原料。

JLS §4.8概述:

更準確地說,原始類型被定義爲是以下之一:其是通過取一個通用類型的名稱形成

  • 引用類型沒有伴隨類型參數列表的聲明。

  • 元素類型爲原始類型的數組類型。

  • 不是從R.

    的超類或超繼承

注意最後一顆子彈原始類型R的非靜態成員類型。

+0

最後一個項目符號實際上是指內部類(非靜態成員*類型*),而不是字段。 – Radiodef