Why calling method with generic return on a generic class is considered unsafe by javac?

后端 未结 4 1669
南笙
南笙 2020-12-06 16:42

Consider the following code:

public class Main {
    public static class NormalClass {
        public Class method() {
            return Inte         


        
相关标签:
4条回答
  • 2020-12-06 17:02

    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.

    Java Language Specification

    0 讨论(0)
  • 2020-12-06 17:03

    In order to be compatible with Java 1.4 compiler assumes that if you drop the generic arguments on instance type declaration, then you work with the special version of the class where no generics exist at all. And it issues a warning if you mix a Java 1.4 non-generic code with Java 1.5+ generic code. That's easier than trying to figure out whether generic return type of your method is actually independent from parameters. You can always @SuppressWarning if you don't like it.

    0 讨论(0)
  • 2020-12-06 17:04

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-06 17:06

    This might have to do with the instantiation of GenericClass which is a parameterized type and hence type arguments are needed in it. The warning vanishes if we do something like the following

    GenericClass<String> unsafeInstance = new GenericClass<String>();
                              OR
    GenericClass<?> unsafeInstance = new GenericClass();
    

    As per my point of view, the reference "unsafeInstance" refers to a class which is generic in nature as opposed to "safeInstance". Thus the compiler may want the type information be associated to the reference before any method is called using it in code.

    0 讨论(0)
提交回复
热议问题