与列表原始类型提供了编译错误

问题描述:

我有以下的通用类:与列表<String>原始类型提供了编译错误

import java.util.ArrayList; 
import java.util.List; 

public class GenericRaw<T> { 
    public List<String> get() { 
     return new ArrayList<>(); 
    } 
} 

让我们看看它的使用的情况下:

public class Usage { 
    public void doSomething() { 
     GenericRaw base = new GenericRaw(); 
     for (String x : base.get()) { } 
    } 
} 

对于这个代码理念不给任何编译错误,但Java编译器本身:

java:不兼容的类型 必需:java.lang.String 发现:java.lang.Object继承

上重现JDK 1.6.0_33以及对JDK 1.7.0_17。

有人可以帮我解释这个问题吗?

我调查的结果。 以下变体可成功编译:

public void doSomething() { 
    GenericRaw<?> base = new GenericRaw(); 
    for (String x : base.get()) { } 
} 

甚至:

public void doSomething() { 
    GenericRaw base = new GenericRaw(); 
    List<String> list = base.get(); 
    for (String x : list) { } 
} 
+0

我同意这是重复的[http://stackoverflow.com/questions/11007723/combining-raw-types-and-generic-methods](http://stackoverflow.com/questions/11007723/combining -raw-types-and-generic-methods)就在不同的条件下。 –

有人可以帮助我这个问题的解释呢?

肯定。它的下面的原料类型的JLS的描述,在section 4.8

为了促进与非通用遗留码接口,有可能作为一种类型使用擦除(§4.6)的参数化类型的(§4.5)或擦除其元素类型为参数化类型的数组类型(第10.1节)。这种类型被称为原始类型。

GenericRaw<T>erasure是:

public class GenericRaw { 
    public List get() { ... } 
} 

因为:

类型擦除也映射签名(§8.4.2)构造或方法不具有一个签名的参数化类型或类型变量。构造函数或方法签名的删除是一个由与s相同名称和s中所有形式参数类型的删除组成的签名。

构造函数或方法(第8.4.4节)的类型参数以及方法的返回类型(第8.4.5节)在擦除构造函数或方法的签名时也会进行擦除。

+0

非常感谢您的帮助! –