Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在OpenJDK和Oracle中,匿名内部类直接调用外部类实例方法有什么区别?_Java_Javac_Openjdk - Fatal编程技术网

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

Java 在OpenJDK和Oracle中,匿名内部类直接调用外部类实例方法有什么区别?,java,javac,openjdk,Java,Javac,Openjdk,今天,我回顾了相同的Android代码,发现了一个奇怪的现象 它是直接称为外部类实例方法的匿名内部类 在我看来,直接调用一个方法相当于在方法前面直接添加this,而this是一个内部类的实例 根据此逻辑,外部类的实例直接在匿名内部类中调用,这将导致编译错误 但实际上编译这个应用程序,并没有问题。运行日志正常 因此,编写一个简单的演示来验证前面的概念是错误的。代码显示如下: public class InnerClass { public static void main(String[]

今天,我回顾了相同的Android代码,发现了一个奇怪的现象

它是直接称为外部类实例方法的匿名内部类

在我看来,直接调用一个方法相当于在方法前面直接添加
this
,而
this
是一个内部类的实例

根据此逻辑,外部类的实例直接在匿名内部类中调用,这将导致编译错误

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

因此,编写一个简单的演示来验证前面的概念是错误的。代码显示如下:

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;
    }
}
在甲骨文中:

在OpenJDK中:

那么,在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;
    }
}
公共类内部类{
公共静态void main(字符串[]args){
新的InnerClass().process();
}
公共程序(){
新线程(){
@凌驾
公开募捐{
//根据我的观点
//toString(“测试”)
// 
//此.toString(“测试”)
//“this”是Thread的实例
//我的观点有什么错误?
System.out.println(toString(“测试”));
}
}.start();
}
公共字符串到字符串(字符串){
返回字符串;
}
}
问题是

        public void run() {
            System.out.println(toString("test"));
        }
正在匿名
线程
子类上调用
toString
,即
Thread::toString()
。没有
Thread::toString(String)
,并且不考虑封闭范围中的
toString(String)
方法

JLS声明,如果内部类中没有具有所需名称的方法,它将仅检查封闭/外部类中的方法。见:

如果表单为MethodName,即仅为标识符,则:

  • 如果标识符出现在可见方法声明的范围内 使用该名称(§6.3,§6.4.1),然后:

    • 如果有一个封闭类型声明,该方法是该声明的一个成员,那么让T作为最内部的类型声明。班级或 搜索的接口是T

      此搜索策略称为“梳规则”。在查找之前,它会在嵌套类的超类层次结构中有效地查找方法 用于封闭类及其超类层次结构中的方法。看见 §6.5.7.1为例

至于为什么OpenJDKJava7接受您的测试类。。。。如果这是真的,我会称之为编译器错误。但这将是一个普通的Java7错误,而不是OpenJDK特有的错误。对于同一版本的Oracle和OpenJDK版本,
javac
codebase(AFAIK)是相同的

有趣的是,我有一个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

所以。。。大概您应该重新运行OpenJDKJava7测试,并确保编译的源代码相同

还请注意,一个是Java 8,另一个是Java 7。@MacStevins我看到了url.,但我找不到详细信息。例如,javac句柄匿名内部类直接调用外部类的实例方法的区别为什么要比较Windows和Unix?Java 7到Java 8?在你说软件本身存在差异之前,先限制外部差异。OpenJDK和OracleJavaC之间没有这种差异(将来也不会有)。您只是在比较Java7和Java8(在不同的操作系统和地区)。
toString(String)
不是
toString()
。在这两种情况下,它都是
Thread#toString
我知道………嗯,为什么你说它调用Object.toString()?因为在这种情况下,名称才是最重要的。请参阅我刚才引用的JLS文本。的确,请通读全文。啊。。。。我明白你的意思。