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

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

问题描述

考虑下面的代码:

  public class Main {
public static class NormalClass {
public类<整数> 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:警告:[unchecked]未经检查的转换
类<整数> unsafeValue = unsafeInstance.method();
^
要求:Class< Integer>
发现:Class
1警告

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



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

解决方案

允许原始类型确保与代码的兼容性在仿制药引入之前撰写。原始类型只需忽略来自所有方法参数和返回类型的所有类型信息,甚至与该类的类型参数无关的类型信息。正如你所发现的,这可能会导致奇怪的结果。但它比这更奇怪。例如,这个编译。

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


Consider the following code:

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

If I compile it with:

$ javac -Xlint:unchecked Main.java 

It returns:

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.

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

解决方案

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天全站免登陆