7
public class POJO<T> {

    private List<Integer> integer = new ArrayList<Integer>();

    public POJO() {
        integer.add(1);
        integer.add(2);
    }

    public List<Integer> getInteger() {
        return integer;
    }

    public static void main(String[] args) {
        POJO pojo = new POJO();
        List<String> integer = pojo.getInteger(); // No compile error?
        System.out.println(integer); // prints [1, 2]
    }
}

以下行如何编译:

List<String> integer = pojo.getInteger();

提供getInteger()的类型如下

public List<Integer> getInteger()
4

3 回答 3

7

I found a reference in the JLS 4.8 that backs up what @PeterLawrey says:

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

So all instance methods of your raw POJO object are erased, including those that don't reference the type T of POJO<T>, which means (JLS 4.6):

The type parameters of a [...] method (§8.4.4), and the return type (§8.4.5) of a method, also undergo erasure if the [...] method's signature is erased.

于 2012-08-31T11:16:23.747 回答
7

Aspojo未声明为泛型

POJO pojo = new POJO();

编译器假定您在预通用代码中使用它。即在编写代码后添加泛型。所以当你这样做时

List<String> integer = pojo.getInteger(); 

您会收到警告而不是错误。

即,如果类型是非泛型的,则所有泛型检查都将关闭,而不仅仅是那些与您没有提供的类型相关的检查。我相信这是为了最大程度的向后兼容性。

为了比较。

Map mapOfInteger = new Map(); // no generics
Set<String> entries = map.entrySet(); // gives a warning, not an error.

在这个例子中,如果不是泛型,您可能希望Set<Entry<K, V>>成为Set<Entry>非泛型,但编译器会退回到将类视为非泛型Set

于 2012-08-31T10:51:43.433 回答
2

这是一个未经检查的分配,出于兼容性原因不被视为错误。

请参阅与旧代码互操作

实际上,分配是合法的,但它会产生未经检查的警告。

于 2012-08-31T10:57:57.203 回答