Java 10 var and capture variable

后端 未结 1 2061
既然无缘
既然无缘 2021-02-05 16:10

I\'m reading the JEP 286 but I don\'t understand this part:

Capture variables, and types with nested capture variables, are projected to supertypes that

相关标签:
1条回答
  • 2021-02-05 16:57

    var allows you to infer a non-denotable type:

    var x = new Object() {
        int i = 10;
    };
    
    System.out.println(x.i); // works; `x` has the non-denotable type of the annonymous class
    

    So theoretically that would allow you to infer a wildcard type. But what this text is saying is that that is not possible, because the wildcard is replaced by it's upper bound, or by a new capture variable in the inferred type.

    Take for instance this snippet of code:

    List<String> l1 = new ArrayList<>();
    l1.add("Hello");
    List<?> l2 = l1;
    
    var x = l2.get(0);
    l2.add(x); // error
    

    Here, instead of the type of x being inferred to the exact type of the wild card, which would make the last line compile. Instead it is inferred to it's upper bound, which is Object, and you get the (Eclipse) error message:

    The method add(capture#2-of ?) in the type List<capture#2-of ?> is not applicable for the arguments (Object)
    

    Where you can see that the type of x is Object.

    That is the part

    This mapping replaces capture variables with their upper bounds


    The second part

    ... and replaces type arguments mentioning capture variables with bounded wildcards

    Is talking about a situation like this:

    List<String> l1 = new ArrayList<>();
    l1.add("Hello");
    List<?> l2 = l1;
    var l3 = l2; // type of 'l3' is List<?>, but not the same '?' as 'l2'
    
    l3.add(l2.get(0)); // error
    

    This doesn't compile either, because the type of l3 is not the exact same type as the type of l2, which means that the type returned from l2.get(0) is not the same type as required by l3.add(...). The error here is:

    The method add(capture#2-of ?) in the type List<capture#2-of ?> is not applicable for the arguments (capture#3-of ?)
    

    And you see that both of the capture variables are distinct, meaning that the type of l3 is not exactly the type of l2, but the capture variable of the type of l2 in the inferred type is replaced by a wildcard with the same bound, for which a new capture variable is then created.

    So for a type List<capture#1-of ?> the inferred type is List<?>, and then the compiler creates a new capture variable for that wildcard, yielding List<capture#2-of ?> (though the numbering might work differently in practice, the key is that the 2 capture variables are different).

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