gpt4 book ai didi

java - 为什么 Object 和 var 变量的行为不同?

转载 作者:行者123 更新时间:2023-12-02 07:44:23 24 4
gpt4 key购买 nike

有人可以解释一下o2的行为吗?是因为编译器优化吗? JLS 中是否有记录?

public class Test {
public static void main(String[] args) {
Object o1 = new Object() {
String getSomething() {
return "AAA";
}
};
// o1.getSomething(); // FAILS
String methods1 = Arrays.toString(o1.getClass().getMethods());
var o2 = new Object() {
String getSomething() {
return "AAA";
}
};
o2.getSomething(); // OK
String methods2 = Arrays.toString(o2.getClass().getMethods());
System.out.println(methods1.equals(methods2));
}
}

产生的输出是

true

[更新]

经过一些富有成效且有用的讨论后,我想我可以理解这种行为(如果我的假设错误,请发表评论)。

首先,感谢 @user207421,他解释了 Java 编译器将 o2 的类型视为与 RHS 相同,其中:

  • 扩展对象
  • getSomething 方法

然后感谢@Joachim Sauer指出了 JLS 中的正确位置。

一些更多相关的 JLS 报价:

The type of the local variable is the upward projection of T with respect to all synthetic type variables mentioned by T (§4.10.5).

Upward projection is applied to the type of the initializer when determining the type of the variable. If the type of the initializer contains capture variables, this projection maps the type of the initializer to a supertype that does not contain capture variables.

While it would be possible to allow the type of the variable to mention capture variables, by projecting them away we enforce an attractive invariant that the scope of a capture variable is never larger than the statement containing the expression whose type is captured. Informally, capture variables cannot "leak" into subsequent statements.

问题:我们可以说“捕获变量”在问题的上下文中也指的是 getSomething() 吗?

最后,感谢 @Slaw 指出 getSomething 被声明为包私有(private),因此 getMethods 没有返回。

任何评论/更正表示赞赏。

最佳答案

JEP 286: Local-Variable Type Inference 中表示为不可表示类型的部分状态:

Anonymous class types cannot be named, but they're easily understood—they're just classes. Allowing variables to have anonymous class types introduces a useful shorthand for declaring a singleton instance of a local class. We allow them.

因此,考虑到类实例已创建并推断为匿名类,则允许使用 var 调用的方法进行编译,进一步允许调用该方法。

Local Variable Declarators and Type规范的部分还提到了这一点作为附注以及示例:

var d = new Object() {};  // d has the type of the anonymous class

Note that some variables declared with var cannot be declared with an explicit type, because the type of the variable is not denotable.

另一方面,在第一个实例中,您尝试执行的操作看起来像 Invoking a method of an anonymous class ,由于 o1 的类型被推断为 Object 并且它没有名为 getSomething 的方法,因此失败。如果您要调用方法 getSomething 并修复其中的编译,则可以使用

Object o1 = new Object() {
String getSomething() {
System.out.println("something happened");
return "AAA";
}
}.getSomething();

关于java - 为什么 Object 和 var 变量的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59282435/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com