我在读 JEP 286 但我不明白这一部分:
使用嵌套捕获变量捕获变量和类型 投射到没有提到捕获变量的超类型。这个 映射将捕获变量替换为其上限和 替换带有有界的捕获变量的类型参数 通配符(然后重复)。这保留了传统上受限制的 捕获变量的范围,仅在单个范围内考虑 声明。
谁能让我在Java代码中具体说明它的含义?
我在读 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 ?>
(虽然编号在实践中可能有不同的作用,关键是2个捕获变量是不同的)。
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 ?>
(虽然编号在实践中可能有不同的作用,关键是2个捕获变量是不同的)。