4

この質問はフォローアップです: 同じ名前の匿名クラスの外部でメソッドを呼び出せないのはなぜですか

この前の質問はなぜ答えますが、javacrun(int bar)? (run(42) が失敗する理由については、前の質問を参照してください)

ダメなら仕様によるものでしょうか?あいまいなコードを生成しますか? 私のポイントは、これはバグだと思います。前の質問でこのコードがコンパイルに失敗する理由を説明しましたが、現在のレベルで一致するものが見つからない場合、javac がツリーの上位を検索した場合にコンパイルする必要があると思います。すなわち。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) {
    }
}
4

3 に答える 3

4

この javac の動作は仕様に準拠しています。Java 言語仕様の§15.12 メソッド呼び出し式を参照してください。具体的には、非修飾メソッド呼び出しの意味を説明する「コンパイル時のステップ 1」の下の段落を参照してください。

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

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

于 2008-10-31T17:33:50.020 に答える
1

試す

NotApplicable.this.run(42);

代わりは。

于 2008-10-31T17:37:20.280 に答える
1

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

匿名クラスはすでにかなり醜いです - このビットを明示的にすることはまったく気にしません。

于 2008-10-31T17:19:03.403 に答える