为什么javac认为在泛型类上使用泛型返回调用方法是不安全的?

Jua*_*pes 16 java generics javac raw-types

请考虑以下代码:

public class Main {
    public static class NormalClass {
        public Class<Integer> method() {
            return Integer.class;
        }
    }

    public static class GenericClass<T> {
        public Class<Integer> method() {
            return Integer.class;
        }
    }

    public static void main(String... args) {
        NormalClass safeInstance = new NormalClass();
        Class<Integer> safeValue = safeInstance.method();

        GenericClass unsafeInstance = new GenericClass();
        Class<Integer> unsafeValue = unsafeInstance.method();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我编译它:

$ javac -Xlint:unchecked Main.java 
Run Code Online (Sandbox Code Playgroud)

它返回:

Main.java:16: warning: [unchecked] unchecked conversion
        Class<Integer> unsafeValue = unsafeInstance.method();
                                                          ^
  required: Class<Integer>
  found:    Class
1 warning
Run Code Online (Sandbox Code Playgroud)

请注意,即使返回类型没有引用泛型类型,也只会将通用方法视为不安全.

这是一个javac错误吗?或者有一个更深层次的原因,我没有考虑到这一点?

Pau*_*ton 12

允许原始类型确保与引入泛型之前编写的代码兼容.原始类型通过简单地忽略来自所有方法参数和返回类型的所有类型信息来工作,甚至是与类的类型参数无关的类型信息.正如您所发现的那样,这可能会导致奇怪的结果.但它比这更奇怪.例如,这个编译.

public class Main {

    public static class GenericClass<T> {
        public void foo(Class<Integer> clazz) {
        }
    }

    public static void main(String... args) {
        GenericClass unsafeInstance = new GenericClass();
        unsafeInstance.foo(String.class);
    }
}
Run Code Online (Sandbox Code Playgroud)