为什么我不能在同名的匿名类之外调用方法

Pyr*_*cal 2 java methods javac anonymous-class

最后的代码产生编译错误:

NotApplicable.java:7: run() in  cannot be applied to (int)
                run(42);
                ^
1 error
Run Code Online (Sandbox Code Playgroud)

问题是为什么?为什么javac认为我调用run(),并且找不到run(int bar)?它正确地称为foo(int bar).为什么我必须使用NotApplicable.this.run(42);?这是一个错误吗?

public class NotApplicable {

    public NotApplicable() {
        new Runnable() {
            public void run() {
                foo(42);
                run(42);
                // uncomment below to fix
                //NotApplicable.this.run(42);
            }
        };
    }

    private void run(int bar) {
    }

    public void foo(int bar) {
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*x B 16

您的代码示例行为的解释this是定义为您当前"最"的类.在这种情况下,你是匿名内部类中的"最"的子类runnable并且没有匹配的方法run(int).要扩大搜索范围,this请通过说明指定要使用的搜索NotApplicable.this.run(42).

jvm将评估如下:

this- >当前正在执行Runnablewith method的实例run()

NotApplicable.this- >当前正在执行NotApplicablewith method的实例run(int)

编译器将查找嵌套树以查找与方法的NAME匹配的第一个方法. - 感谢DJClayworth的澄清

匿名内部类不是外部类的子类.由于这种关系,内部类和外部类应该能够具有完全相同签名的方法,并且最内部代码块应该能够识别它想要运行的方法.

public class Outer{

    public Outer() {
        new Runnable() {
            public void printit() {
                System.out.println( "Anonymous Inner" );
            }
            public void run() {
                printit(); // prints "Anonymous Inner"
                this.printit(); //prints "Anonymous Inner"

                // would not be possible to execute next line without this behavior
                Outer.this.printit(); //prints "Outer" 
            }
        };
    }

    public void printit() {
        System.out.println( "Outer" );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是正确的,除了关于"即使两个方法都没有命名为'run'"也会展示这种行为.编译器将查找嵌套树以查找与方法的NAME匹配的第一个方法. (2认同)