为什么 javac 会抱怨与类的类型参数无关的泛型? [英] Why does javac complain about generics unrelated to the class' type arguments?

查看:49
本文介绍了为什么 javac 会抱怨与类的类型参数无关的泛型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请按顺序阅读代码中的注释,问题详情在那里.
为什么会出现这种差异?
如果可能,请引用 JLS.

Please read the comments in the code in order, the question details are there.
Why is this difference happening?
Please quote the JLS if possible.

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 兼容,因为当我用以下代码编译上面的代码时,它给出了相同的错误/警告.

Side note

I originally found this in IntelliJ IDEA, but I guess that compiler is compatible with javac because when I compiled the above code with the following it gave the same errors/warnings.

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

推荐答案

来自 JLS 4.8 原始类型

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

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged.

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

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.

这 - 如果你仔细阅读 - 意味着所有类型都被擦除,而不仅仅是你遗漏的类型.

Which - if you read it carefully - implies that all types are erased, not just the type you left out.

这篇关于为什么 javac 会抱怨与类的类型参数无关的泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆