Java 10 var 和捕获变量

标签 java java-10

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

Capture variables, and types with nested capture variables, are projected to supertypes that do not mention capture variables. This mapping replaces capture variables with their upper bounds and replaces type arguments mentioning capture variables with bounded wildcards (and then recurs). This preserves the traditionally limited scope of capture variables, which are only considered within a single statement.

谁能给我一个具体的 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 .

就是这部分

This mapping replaces capture variables with their upper bounds


第二部分

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

正在谈论这样的情况:

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 个捕获变量是不同的)。

关于Java 10 var 和捕获变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51630871/

相关文章:

java - 在哪里放置在 ext 中添加的自定义 jar 以及 jdk 10 的认可文件夹

java - 如何使用 Spring WebFlux Reactive 方式在处理函数中使用 Mono 和 Flux

java - Unity异常: Unable to find suitable JDK installation

java - java中抛出异常

java - 如何在 Java 中创建 bash "pipe"命令的模拟

java - 可完成的 future : Invoke a void function asynchronusly

java - jmeter中如何实现csv文件的多个http请求?

java - 如何处理 Java 11 中缺少的 Swing PLAF 类?

maven-3 - org.jooq.codegen.GeneratorException : Error while reading XML configuration

java - JPasswordField.getPassword() 的安全原因是什么?