gpt4 book ai didi

javac - OpenJDK和Oracle中匿名内部类直接调用外部类实例方法有什么区别?

转载 作者:行者123 更新时间:2023-12-02 11:53:46 25 4
gpt4 key购买 nike

今天,我查看了相同的Android代码,发现了一个奇怪的现象。

是匿名内部类直接调用外部类实例方法。

在我看来,直接调用方法就相当于加上this就在该方法之前,并且 this是内部类的实例。

按照这个逻辑,在匿名内部类中直接调用外部类的实例,就会导致编译错误。

但是实际编译这个应用程序,并没有问题。并且运行日志正常。

因此,写一个简单的Demo来验证之前的概念是错误的。代码如下:

public class InnerClass {
public static void main(String[] args) {
new InnerClass().process();
}

public void process() {
new Thread() {
@Override
public void run() {
System.out.println(toString("test"));
}
}.start();
}

public String toString(String string) {
return string;
}
}

在甲骨文中:
enter image description here

在 OpenJDK 中:
enter image description here

那么,OpenJDK和Oracle中匿名内部类直接调用外部类实例方法有什么区别呢?

在哪里可以找到文档来了解这些差异?

我很努力,但没有得到明确的答案。

谢谢。

附注

根据我的观点

public class InnerClass {
public static void main(String[] args) {
new InnerClass().process();
}

public void process() {
new Thread() {
@Override
public void run() {
// In According to my point of view
// toString("test")
// <==>
// this.toString("test")
// and `this` is the instance of Thread
// what's the error of my view?
System.out.println(toString("test"));
}
}.start();
}

public String toString(String string) {
return string;
}
}

image

最佳答案

问题在于

        public void run() {
System.out.println(toString("test"));
}

正在匿名Thread子类上调用toString,即Thread::toString()。没有 Thread::toString(String),并且不考虑封闭范围中的 toString(String) 方法。

JLS 声明,如果内部类中没有具有所需名称的方法,它只会检查封闭/外部类的方法。请参阅JLS 15.12.1 :

If the form is MethodName, that is, just an Identifier, then:

  • If the Identifier appears in the scope of a visible method declaration with that name (§6.3, §6.4.1), then:

    • If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T.

      This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking for methods in an enclosing class and its superclass hierarchy. See §6.5.7.1 for an example.

至于为什么 OpenJDK Java 7 接受你的测试类......如果这确实是真的,我会称之为编译器错误。但这是 Java 7 的一个普遍错误,而不是 OpenJDK 特有的错误。对于同一版本的 Oracle 和 OpenJDK 版本,javac 代码库(据我所知)是相同的。

有趣的是,我有一份 Oracle Java 6 的副本,该版本的 javac 也将此称为编译错误。

$ /usr/java/jdk1.6.0_45/bin/javac InnerClass.java 
InnerClass.java:10: cannot find symbol
symbol: method toString(java.lang.String)
System.out.println(toString("test"));
^
1 error

所以...也许...您应该重新运行 OpenJDK Java 7 测试,并确保您正在编译相同的源代码!

关于javac - OpenJDK和Oracle中匿名内部类直接调用外部类实例方法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47725077/

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