我正在阅读JEP 286,但是我不明白这一部分:



谁能在Java代码中让我成为具体示例的含义?

最佳答案

var允许您推断不可表示的类型:

var x = new Object() {
    int i = 10;
};

System.out.println(x.i); // works; `x` has the non-denotable type of the annonymous class

因此,从理论上讲,这将允许您推断通配符类型。但是这段文字说的是不可能的,因为通配符被它的上限或推断类型中的新捕获变量所代替。

以下面的代码片段为例:
List<String> l1 = new ArrayList<>();
l1.add("Hello");
List<?> l2 = l1;

var x = l2.get(0);
l2.add(x); // error

在这里,不是将x的类型推断为通配符的确切类型,否则将使最后一行进行编译。相反,它被推断为它的上限,即Object,并且您收到(Eclipse)错误消息:
The method add(capture#2-of ?) in the type List<capture#2-of ?> is not applicable for the arguments (Object)

在这里您可以看到x的类型是Object

那是一部分



第二部分



在谈论这样的情况:
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

这也不编译,因为l3的类型与l2的类型不完全相同,这意味着l2.get(0)返回的类型与l3.add(...)所要求的类型不同。这里的错误是:
The method add(capture#2-of ?) in the type List<capture#2-of ?> is not applicable for the arguments (capture#3-of ?)

您会看到这两个捕获变量是不同的,这意味着l3的类型并不完全是l2的类型,但是推断类型中l2的类型的捕获变量被具有相同界限的通配符替换,例如然后创建一个新的捕获变量。

因此,对于List<capture#1-of ?>类型,推断出的类型为List<?>,然后编译器为该通配符创建一个新的捕获变量,产生List<capture#2-of ?>(尽管编号在实践中可能会有所不同,但关键是两个捕获变量是不同的)。

10-05 21:37