【问题标题】:Why does javac complain about generics unrelated to the class' type arguments? [duplicate]为什么 javac 抱怨与类的类型参数无关的泛型? [复制]
【发布时间】:2014-12-05 11:14:45
【问题描述】:

请按顺序阅读代码中的cmets,问题详情都有。
为什么会出现这种差异?
如果可能,请引用 JLS。

import java.util.*;

/**
 * Suppose I have a generic class
 * @param <T> with a type argument.
 */
class Generic<T> {
    // Apart from using T normally,
    T paramMethod() { return null; }
    // the class' interface also contains Generic Java Collections
    // which are not using T, but unrelated types.
    List<Integer> unrelatedMethod() { return null; }
}

@SuppressWarnings("unused")
public class Test {
    // If I use the class properly (with qualified type arguments)
    void properUsage() {
        Generic<String> g = new Generic<String>();

        // everything works fine.
        String s = g.paramMethod();
        List<Integer> pos = g.unrelatedMethod();

        // OK error: incompatible types: List<String> := List<Integer>
        List<String> thisShouldErrorCompile = g.unrelatedMethod();
    }

    // But when I use the raw type, *ALL* the generics support is gone, even the Collections'.
    void rawUsage() {
        // Using Generic<?> as the type turns fixes the warnings below.
        Generic g = new Generic();

        // OK error: incompatible types: String := Object
        String s = g.paramMethod();

        // WTF warning: unchecked conversion: List<Integer> := raw List
        List<Integer> pos = g.unrelatedMethod();

        // WTF warning: unchecked conversion: List<String> := raw List
        List<String> thisShouldErrorCompile = g.unrelatedMethod();
    }
}

旁注

我最初在 IntelliJ IDEA 中发现了这个,但我猜编译器与 javac 兼容,因为当我使用以下代码编译上述代码时,它给出了相同的错误/警告。

$ javac -version
javac 1.7.0_05
$ javac Test.java -Xlint:unchecked
...
$ javac Test.java -Xlint:unchecked -source 1.5 -target 1.5
...

【问题讨论】:

    标签: java generics javac unchecked


    【解决方案1】:

    来自JLS 4.8 Raw Types

    仅允许使用原始类型作为对遗留代码兼容性的让步。强烈建议不要在将泛型引入 Java 编程语言后编写的代码中使用原始类型。

    未从其超类或超接口继承的原始类型 C 的构造函数(第 8.8 节)、实例方法(第 8.4 节、第 9.4 节)或非静态字段(第 8.3 节)的类型是原始类型对应于 C 对应的泛型声明中擦除其类型的类型。

    如果您仔细阅读,这意味着 所有 类型都被删除,而不仅仅是您遗漏的类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多