为什么 javac 认为在泛型类上调用具有泛型返回的方法是不安全的? [英] Why calling method with generic return on a generic class is considered unsafe by javac?

查看:27
本文介绍了为什么 javac 认为在泛型类上调用具有泛型返回的方法是不安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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

如果我编译它:

$ javac -Xlint:unchecked Main.java 

它返回:

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

请注意只有泛型方法被认为是不安全的,即使返回类型上没有引用泛型类型.

Please note that only the generic method is considered unsafe, even if no generic type is referenced on the return type.

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

Is this a javac bug? Or there is a deeper reason for this I'm not taking into account?

推荐答案

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

Raw types were allowed to ensure compatibility with code written before generics were introduced. Raw types work by simply ignoring all type information from all method arguments and return types, even type information that is not related to the type parameter of the class. This can lead to strange results, as you have found. But it gets even stranger than this. For example, this compiles.

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);
    }
}

这篇关于为什么 javac 认为在泛型类上调用具有泛型返回的方法是不安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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