Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.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
javac应该在同名匿名类之外找到方法吗?_Java_Methods_Javac_Anonymous Class - Fatal编程技术网

javac应该在同名匿名类之外找到方法吗?

javac应该在同名匿名类之外找到方法吗?,java,methods,javac,anonymous-class,Java,Methods,Javac,Anonymous Class,这个问题是对以下问题的后续: 前面的问题回答了为什么,但现在我想知道javac是否应该找到run(int-bar)?(请参阅上一个问题,了解运行(42)失败的原因) 如果不应该,是因为规格吗?它会产生不明确的代码吗?我的观点是,我认为这是一个错误。虽然前面的问题解释了为什么这段代码无法编译,但我觉得如果javac在树中搜索得更高,如果它在当前级别上找不到匹配项,那么它应该编译。例如,如果this.run()不匹配,它应该自动检查run方法的notapplicatable.this 还要注意,f

这个问题是对以下问题的后续:

前面的问题回答了为什么,但现在我想知道javac是否应该找到run(int-bar)?(请参阅上一个问题,了解运行(42)失败的原因)

如果不应该,是因为规格吗?它会产生不明确的代码吗?我的观点是,我认为这是一个错误。虽然前面的问题解释了为什么这段代码无法编译,但我觉得如果javac在树中搜索得更高,如果它在当前级别上找不到匹配项,那么它应该编译。例如,如果this.run()不匹配,它应该自动检查run方法的notapplicatable.this

还要注意,foo(int-bar)是正确的。如果您给出不应该找到run(int-bar)的任何原因,它还必须解释为什么会找到foo(int-bar)

public class NotApplicable {

    public NotApplicable() {
        new Runnable() {
            public void run() {

                // this works just fine, it automatically used NotApplicable.this when it couldn't find this.foo
                foo(42);

                // this fails to compile, javac find this.run(), and it does not match
                run(42);

                // to force javac to find run(int bar) you must use the following
                //NotApplicable.this.run(42);
            }
        };
    }

    private void run(int bar) {
    }

    public void foo(int bar) {
    }
}

对我来说,这听起来像是一个模棱两可和脆弱性的秘诀——一旦在基类中添加了一个新方法(好吧,对于接口来说不太可能…),代码的含义就会完全改变


匿名类已经很难看了——把这一点显式化一点也不困扰我

javac的这种行为符合规范。请参见Java语言规范,特别是“编译时步骤1”下解释非限定方法调用含义的段落:

如果标识符出现在具有该名称的可见方法声明的范围内(§6.3),则必须有一个包含该方法的类型声明。设T为最内部的此类类型声明。要搜索的类或接口是T

换句话说,在所有封闭作用域中搜索非限定的方法名称,在其中找到名称的最内层“类型声明”(表示类或接口声明)是将搜索整个签名的声明(在“编译时步骤2”)。

Try

NotApplicable.this.run(42);

相反。

好的,那么为什么允许javac查找foo(int-bar)?这是同一个食谱,没错。呸,真是一团糟。给我合适的闭包:)谢谢,我想我理解这个规范。现在我可以说这是一个糟糕的规范,应该修改。编译时步骤1应该包括匿名类的封闭类。请注意,在我写这个答案的时候,问题中没有包含相同代码位的注释。