【问题标题】:Raw Type with List<String> gives compilation error [duplicate]带有 List<String> 的原始类型给出编译错误 [重复]
【发布时间】:2013-04-02 18:19:54
【问题描述】:

我有以下通用类:

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()) {   }
    }
}

对于这段代码,Idea 没有给出任何编译错误,但 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) {   }
}

【问题讨论】:

标签: java generics compiler-construction intellij-idea


【解决方案1】:

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

当然。它遵循 JLS 在 section 4.8 中对原始类型的描述:

为了方便与非通用遗留代码的交互,可以使用参数化类型 (§4.5) 的擦除 (§4.6) 或元素类型为的数组类型 (§10.1) 的擦除作为类型参数化类型。这种类型称为原始类型。

GenericRaw&lt;T&gt;erasure 是:

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

因为:

类型擦除还将构造函数或方法的签名(第 8.4.2 节)映射到没有参数化类型或类型变量的签名。构造函数或方法签名s的擦除是由与s同名的签名和s中给出的所有形参类型的擦除组成。

如果构造函数或方法的签名被擦除,构造函数或方法的类型参数(第 8.4.4 节)和方法的返回类型(第 8.4.5 节)也会被擦除。

【讨论】:

  • 非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 2021-12-12
  • 2020-12-12
相关资源
最近更新 更多