我正在阅读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 ?>
(尽管编号在实践中可能会有所不同,但关键是两个捕获变量是不同的)。