2012-03-23 18 views
0

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

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

+1

匿名の内部クラスの場合、コンパイラはどのようにそれらのメソッドを呼び出すかを知っていますか?なぜあなたはパブリッククラスを作成し、それを匿名クラスを使用する代わりに必要な場所で使用するだけではありませんか? – jzworkman

答えて

2

匿名の内部クラスのメソッドにリフレクションでアクセスできます。 getDeclaredMethods()を参照してください。 IllegalAccessExceptionを避けるため、MethodsetAccessible(true)に電話することを忘れないでください。匿名内部クラスが使い捨てクラス定義の一種であることを考慮してください:

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があるかどうこれはWhat is the security risk of object reflection?

警告を参照してくださいことはできないということに気づきます。一度使用すると、他の場所でそれらをもう一度使用する必要はありません。 @PéterTörökと同じように、あなたの問題についてもっと文脈を伝えるのは難しいですが、そのクラスを制御できたら、そのクラスを非公開にして(プライベートな内部クラスを作る、あるいは公開する)そのメソッドを必要なクラスに公開します。

7

匿名の内部クラスは、匿名の理由から匿名です。参照変数/メソッドパラメータを介してのみ、外部から直接アクセスすることはできません。 (そして、同じ理由で、彼らはあまりにもプライベートです。)私はあなたそのコンパイラが生成した名前(たとえば、OuterClass$1)を用いた反射を経て、このようなクラスにアクセスしようとするかもしれないと思い

、しかしそれは、実装固有のものであり、変更される可能性があり別の匿名の内部クラスを同じ外部クラスまたは次のJVMバージョンに追加する瞬間です。だから、そのような解決策は非常に脆くなるでしょう。

なぜ実際にこれをしたいですか?実際の問題を説明すると、より良い選択肢を提供できる可能性があります。

+0

私は同意しません。非匿名クラスと匿名クラスの唯一の違いは、後者クラスには名前がないことです。その理由は、簡潔さであり、セキュリティではありません。だから匿名クラスの理由はパブリックにすることはできませんが、構文は提案されていません。私見では。 – Dims

+0

+1インスタンスを持っている場合はコンパイラ生成のクラス名を使用する必要はありません(これは匿名の内部クラスに固有です)。 –

+0

@XaviLópez、確かに。インスタンスを持っている場合は、なぜ反射が必要ですか? –

1

デフォルトでは、匿名の内部クラスはプライベートです。反射で使用する場合はこちらをご覧ください。Java reflection: How can I retrieve anonymous inner classes?

+1

匿名の内部クラスはプライベートではなく、デフォルト(パッケージプライベート)アクセスを持ちます。 –

+0

私の間違いありがとう – aretai

1

匿名の内部クラスには、プライベート(デフォルト)のアクセス権があります。 Java 6では、静的コンテキストでは宣言されていても、他のコンテキストでは最終的ではない場合、finalです。 (私は、彼らが常に最終的なものであるように、これはJavaの7に変更されたことを、信じていますが、テストしていません。Section 15.9.5 of the Java Language Specificationを参照してください。)例えば

、このクラスは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$1foo1)—パッケージプライベート
  • InnerTest$2foo2)—パッケージプライベート
  • InnerTest$3foo3)—パッケージプライベートと最終
  • InnerTest$4foo4)—パッケージ匿名の内部クラスのインスタンスが割り当てられているため、変数のアクセスは無関係であること民間および最終

注意。

関連する問題