2013-04-26 10 views
6

のように、私は反射に非常に新しいですし、私は疑問を持っている:
AccessibleObjectクラスのsetAccessibleメソッドの背後にある理由は、booleanパラメータを持っていますか?

public void setAccessible(boolean flag) throws SecurityException 

この方法は、任意のフィールドやメソッドの新しいアクセス可能であることを表しboolenパラメータフラグを持っています。私たちは、クラスの外からクラスのprivateメソッドにアクセスしようとする場合、例えば
その後、我々はgetDeclaredMethodを使用する方法を取得し、trueとして、アクセシビリティを設定し、それは次のように、呼び出すことができます。シナリオで今method.setAccessible(true);
method.setAccessible(false);を使用する必要があります。例として、publicメソッドがあり、アクセシビリティをfalseに設定した場合に使用できます。しかし、その必要性は何ですか?私の理解は明確ですか?
method.setAccessible(false)のない使用がない場合、我々は以下のようにメソッドシグネチャを変更することができます。

public void setAccessible() throws SecurityException 
+1

あなたは、コードのプログラマが**意図しなかった状態で反射下のコードを残したくない** 。あなたは ?検査のためにリフレクションを使用して_unlock_コードを作成しましたが、後で_unlocked_にしておきたいですか? –

+0

あなたのポイントを得ました。 –

+0

私は質問を改善できるようにコメントを入れてください。 –

答えて

5

シナリオ:あなたはField.setAccessible(true),と民間分野からの保護を削除し、それを読んで、Field.setAccessible(false).

で元の状態にフィールドを返さ
+9

これを行うことはできますが、いつでもクライアントがフィールドインスタンスを取得できるので、アクセシビリティをfalseに設定してアクセス可能を保護しないため、もう一度setAccessible(true)を使用してフィールドを使用します。さらに、setAccessibleは、フィールドのアクセス可能性も非反射性の方法でも永久に変更しないので、リフレクション以外の方法でフィールドを使用してクライアントから保護することができます。 – mickeymoon

+0

同意しましたが、常にこれを行う必要があります。誰もここで「偽」値を渡すつもりはない。だから、余分なコード行を書こうとするのはなぜですか? – Dennis

14

おそらくあなたは一生のうちにsetAccessible(false)をやっていないでしょう。これは、setAccessibleがaメンバの可視性を永続的に変更しないためです。 method.setAccessible(true)のようなものにすると、methodのインスタンスで、元のソースのメソッドがプライベートであっても、それ以降の呼び出しを行うことができます。

たとえば、このことを考慮してください。

A.java 
******* 
public class A 
{ 
    private void fun(){ 
    .... 
    } 
} 

B.java 
*********** 
public class B{ 

    public void someMeth(){ 
     Class clz = A.class; 
     String funMethod = "fun"; 

     Method method = clz.getDeclaredMethod(funMethod); 
     method.setAccessible(true); 

     method.invoke(); //You can do this, perfectly legal; 

     /** but you cannot do this(below), because fun method's visibilty has been 
      turned on public only for the method instance obtained above **/ 

     new A().fun(); //wrong, compilation error 

     /**now you may want to re-switch the visibility to of fun() on method 
      instance to private so you can use the below line**/ 

     method.setAccessible(false); 

     /** but doing so doesn't make much effect **/ 

    } 

}

+0

あなたの答えをありがとう。 –

+0

あなたは大歓迎です:) – mickeymoon

0
//create class PrivateVarTest { private abc =5; and private getA() {sop()}} 


import java.lang.reflect.Field; 
import java.lang.reflect.Method; 

public class PrivateVariableAcc { 

public static void main(String[] args) throws Exception { 
    PrivateVarTest myClass = new PrivateVarTest(); 

    Field field1 = myClass.getClass().getDeclaredField("a"); 

    field1.setAccessible(true); 

    System.out.println("This is access the private field-" 
      + field1.get(myClass)); 

    Method mm = myClass.getClass().getDeclaredMethod("getA"); 

    mm.setAccessible(true); 
    System.out.println("This is calling the private method-" 
      + mm.invoke(myClass, null)); 

} 

} 
関連する問題