【问题标题】:Should javac find methods outside of an anonymous class of the same name?javac 是否应该在同名的匿名类之外找到方法?
【发布时间】:2008-10-31 17:15:49
【问题描述】:

这个问题是对以下问题的跟进: Why can’t I call a method outside of an anonymous class of the same name

上一个问题回答了why,但是现在我想知道javac是否应该 find run(int bar)? (请参阅上一个问题以了解 run(42) 失败的原因)

如果不应该,是因为规范吗?它会产生模棱两可的代码吗?我的意思是,我认为这是一个错误。虽然前面的问题解释了为什么这段代码无法编译,但我觉得如果 javac 在树中搜索更高的位置,如果它未能在当前级别找到匹配项,它应该编译。 IE。如果 this.run() 不匹配,它应该自动检查 NotApplicable.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) {
    }
}

【问题讨论】:

    标签: java methods javac anonymous-class


    【解决方案1】:

    javac 的这种行为符合规范。请参阅 Java 语言规范中的 §15.12 Method Invocation Expressions,特别是“编译时间步骤 1”下的段落,解释了不合格方法调用的含义:

    如果标识符出现在具有该名称的可见方法声明的范围(第 6.3 节)内,则必须存在该方法是其成员的封闭类型声明。让 T 成为最里面的这种类型声明。要搜索的类或接口是 T。

    换句话说,在所有封闭范围内搜索非限定方法name,并在其中找到名称的最里面的“类型声明”(表示类或接口声明)是将要搜索整个签名的那个(在“编译时间步骤 2”中)。

    【讨论】:

    • 谢谢,我想我了解规范。现在我可以说这是一个糟糕的规范,应该改变。编译时步骤 1 应包括匿名类的封闭类。
    【解决方案2】:

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

    匿名类已经很丑陋了 - 让这点显式一点都不会打扰我。

    【讨论】:

    • 好的,那么为什么允许 javac 查找 foo(int bar)?这是相同的配方。
    • 确实如此。呸,这一切都是一团糟。给我适当的关闭:)
    【解决方案3】:

    试试

    NotApplicable.this.run(42);
    

    改为。

    【讨论】:

    • 请注意,在我撰写此答案时,问题中没有包含相同代码的注释。
    猜你喜欢
    • 1970-01-01
    • 2017-03-03
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多