javacは、同じ名前の匿名クラス外のメソッドを見つける必要がありますか?

StackOverflow https://stackoverflow.com/questions/254260

質問

この質問はフォローアップです: なぜできる& #8217; t同じ名前の匿名クラスの外部のメソッドを呼び出す

この前の質問はなぜと答えますが、javac がrun(int bar)を見つけるべきかどうかを知りたいですか? (run(42)が失敗する理由を確認するには、前の質問を参照してください)

もしそうでなければ、仕様によるものですか?あいまいなコードが生成されますか?私のポイントは、これはバグだと思います。前の質問でこのコードがコンパイルに失敗する理由を説明しましたが、現在のレベルで一致が見つからなかった場合、javacがツリー内でより高い位置を検索した場合はコンパイルする必要があると思います。 IE。 this.run()が一致しない場合、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) {
    }
}
役に立ちましたか?

解決

このjavacの動作は仕様に準拠しています。 § 15.12メソッド呼び出し式 Java言語仕様、特に「コンパイル時間ステップ1」の下の段落修飾されていないメソッド呼び出しの意味の説明:

  

識別子がその名前の可視メソッド宣言のスコープ(§ 6.3)内にある場合、そのメソッドがメンバーである型宣言を囲む必要があります。 Tを最も内側のそのような型宣言にします。検索するクラスまたはインターフェースはTです。

つまり、修飾されていないメソッド name がすべての囲みスコープで検索され、最も内側の「型宣言」が検索されます。 (クラスまたはインターフェース宣言のいずれかを意味します)名前が見つかったものは、署名全体を検索するものです("コンパイル時間ステップ2")。

他のヒント

私には曖昧さと脆弱性のレシピのように聞こえます-新しいメソッドが基本クラスに追加されるとすぐに(大丈夫、インターフェースではない...)、コードの意味が完全に変わります。

匿名クラスはすでにかなりいです-この少しの明示的なクラスを作成しても、まったく気になりません。

試用

NotApplicable.this.run(42);

代わりに。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top