作者:呆保保_369 | 来源:互联网 | 2022-12-08 23:25
我正在阅读JEP 286,但我不明白这一部分:
使用嵌套捕获变量捕获变量和类型会被投射到不提及捕获变量的超类型.此映射将捕获变量替换为其上限,并替换使用有界通配符提示捕获变量的类型参数(然后重复).这保留了传统上有限的捕获变量范围,这些变量仅在单个语句中考虑.
谁能让我在Java代码中具体说明它的含义?
1> Jorn Vernee..:
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 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 is not applicable for the arguments (Object)
你可以在哪里看到的类型x
是Object
.
那是一部分
此映射将捕获变量替换为其上限
第二部分
...并使用有界通配符替换提及捕获变量的类型参数
谈论这样的情况:
List 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 is not applicable for the arguments (capture#3-of ?)
并且您看到两个捕获变量都是不同的,这意味着类型l3
不完全是类型l2
,但是l2
推断类型中的类型的捕获变量被具有相同边界的通配符替换为新的然后创建捕获变量.
所以对于一个类型List
,推断类型是List>
,然后编译器为该通配符创建一个新的捕获变量,产生List
(尽管编号在实践中可能有不同的作用,关键是2个捕获变量是不同的).
@ xdevel2000`List <?>`是一个带有嵌套捕获变量的类型.所以对于`List
`正在投影的超类型是`List <?>`(带通配符),然后编译器会为其创建一个新的捕获变量.
通配符不是正确的类型(它们没有成员,子类型,超类型等),因此捕获转换会在它们用作类型时将它们转换为类型变量.在像`l2.add(x)`这样的情况下,在搜索`l2`类型的成员时会发生捕获转换([List <?>`的成员是捕获转换后的成员](https:/ /docs.oracle.com/javase/specs/jls/se10/html/jls-4.html#jls-4.5.2))在类似`l2.get()`的情况下,[捕获转换特别适用于返回类型](https://docs.oracle.com/javase/specs/jls/se10/html/jls-15.html#jls-15.12.3).