Why is generic of a return type erased when there is an unchecked conversion of a method parameter in Java 8?

后端 未结 4 1838
野趣味
野趣味 2020-12-05 13:22

Consider the following code sample:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
             


        
4条回答
  •  自闭症患者
    2020-12-05 13:49

    This looks like a known compatibility issue reported here and here.

    From the second link:

    The following code which compiled, with warnings, in JDK 7 will not compile in JDK 8:

    import java.util.List;
    class SampleClass {
    
         static class Baz {
             public static List> sampleMethod(Baz param) {
                 return null;
             }
         }
    
         private static void bar(Baz arg) {
             Baz element = Baz.sampleMethod(arg).get(0);
         }
    }
    
    
    

    Compiling this code in JDK 8 produces the following error:

    SampleClass.java:12: error:incompatible types: Object cannot be converted to Baz

    Baz element = Baz.sampleMethod(arg).get(0);
    

    Note: SampleClass.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error

    Deriving from this, the OP's code can be fixed by replacing this line (the type declartion on the right hand side threw me off - I read it as a typed array list which it is not):

    List list = new ArrayList();
    

    with

    List list = new ArrayList();
    

    which will not result in type being being erased from return type of method getProducer(List list)

    Quote from second link again:

    In this example, a raw type is being passed to the sampleMethod(Baz) method which is applicable by subtyping (see the JLS, Java SE 7 Edition, section 15.12.2.2). An unchecked conversion is necessary for the method to be applicable, so its return type is erased (see the JLS, Java SE 7 Edition, section 15.12.2.6). In this case the return type of sampleMethod(Baz) is java.util.List instead of java.util.List> and thus the return type of get(int) is Object, which is not assignment-compatible with Baz.

    提交回复
    热议问题