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