0

匿名の内部クラスはデフォルトでプライベートですか? それらを公開することはできますか?

リフレクションによってメソッドにアクセスする必要があります。

4

4 に答える 4

7

匿名の内部クラスが匿名であるのには理由があります。外部から直接アクセスするためのものではなく、参照変数/メソッド パラメータを介してのみアクセスするためのものです。(そして同じ理由で、それらも非公開です。)

コンパイラによって生成された名前 (例: ) を使用してリフレクション経由でそのようなクラスにアクセスしようとする可能性があると思いますがOuterClass$1、これは実装固有であり、別の匿名内部クラスを同じ外部クラスに追加した瞬間、または次の JVM バージョンで変更される可能性があります。 . したがって、そのような解決策は非常に脆弱です。

なぜあなたは実際にこれをしたいのですか?実際の問題を説明していただければ、より良い代替案を提供できる場合があります。

于 2012-03-23T15:34:13.750 に答える
3

リフレクションを使用して、匿名の内部クラスのメソッドにアクセスできます。を参照してくださいgetDeclaredMethods()。を避けるためにsetAccessible(true)、を呼び出すことを忘れないでください。MethodIllegalAccessException

Object testObject = new Object() {
    private void testMe() { 
        System.out.println("testme");
    }
};
Method m = testObject.getClass().getDeclaredMethod("testMe");
m.setAccessible(true);
m.invoke(testObject); // prints out "testme"

また、SecurityManagerこれが不可能な場合は、オブジェクトリフレクションのセキュリティリスクは何ですか?を参照してください。

警告:匿名の内部クラスは一種の使い捨てクラス定義であることを考慮に入れてください。一度使用すると、他の場所でそれらを二度と必要とすることはありません。@PéterTörökが言ったように、問題についてこれ以上のコンテキストがないとわかりませんが、そのクラスを制御できる場合は、そのクラスの匿名化を解除する(プライベート内部クラスまたはパブリックにする)方がよいでしょう。そのメソッドをそれを必要とするクラスに公開します。

于 2012-03-23T15:35:18.460 に答える
1

匿名の内部クラスはデフォルトでプライベートです。リフレクションで使用する場合は、ここを参照してください-Javaリフレクション:匿名の内部クラスを取得するにはどうすればよいですか?

于 2012-03-23T15:35:18.723 に答える
1

匿名の内部クラスには、パッケージのプライベート (デフォルト) アクセスがあります。Java 6 では、静的コンテキストで宣言されている場合は final ですが、他のコンテキストでは final ではありません。(テストはしていませんが、これは Java 7 で変更されたため、常に最終的なものになっていると思います。Java 言語仕様のセクション 15.9.5 を参照してください。)

たとえば、このクラスには 4 つの匿名内部クラスがあります。

public class InnerTest {
    public Runnable foo1 = new Runnable() {
        public void run() {foo1();}
        void foo1() {}
    };
    private Runnable foo2 = new Runnable() {
        public void run() {foo2();}
        void foo2() {}
    };
    public static Runnable foo3 = new Runnable() {
        public void run() {foo3();}
        void foo3() {}
    };
    private static Runnable foo4 = new Runnable() {
        public void run() {foo4();}
        void foo4() {}
    };
}

javac (バージョン 1.6.0_26) でコンパイルすると、4 つの匿名内部クラスが生成されます。逆コンパイルすると、次のjavap -cことが明らかになります。

  • InnerTest$1( foo1) — パッケージ プライベート
  • InnerTest$2( foo2) — パッケージ プライベート
  • InnerTest$3( foo3) — パッケージの非公開および最終版
  • InnerTest$4( foo4) — パッケージの非公開および最終版

匿名の内部クラス インスタンスが割り当てられている変数へのアクセスは無関係であることに注意してください。

于 2012-03-23T16:24:37.090 に答える