2013-04-26 5 views
6

Ich bin sehr neu in Reflexion und ich habe Zweifel, wie:
Was ist der Grund dafür, dass die setAccessible-Methode der AccessibleObject-Klasse über einen booleschen Parameter verfügt?

public void setAccessible(boolean flag) throws SecurityException 

Diese Methode hat einen boolen Parameter-Flag, die die neue Zugänglichkeit aller Felder oder Methoden gibt.
Ein Beispiel, wenn wir eine private Methode einer Klasse von außerhalb der Klasse zugreifen sollen versuchen dann holen wir die Methode getDeclaredMethod und stellen Sie die Zugänglichkeit als true verwenden, so kann sie aufgerufen werden, wie: method.setAccessible(true);
Jetzt, in dem Szenario wir sollten method.setAccessible(false); verwenden, für ein Beispiel kann es verwendet werden, wenn es eine public Methode gibt und wir die Zugänglichkeit als falsch festlegen. Aber was ist das nötig? Ist mein Verständnis klar?
Wenn es keine Verwendung von method.setAccessible(false) dann können wir die Methode Signatur ändern wie:

public void setAccessible() throws SecurityException 
+1

Sie wollen nicht den Code unter Reflexion in einem Zustand lassen, die der Programmierer des Codes ** nicht beabsichtigt ** . Machst du ? Du hast Reflektion benutzt, um ein Stück Code zur Inspektion zu öffnen. Willst du es danach _unlocked_ lassen? –

+0

Yup. habe deinen Standpunkt verstanden. –

+0

Downvoater können Sie bitte einen Kommentar, so dass ich meine Frage verbessern kann. –

Antwort

5

Szenario: Sie Schutz vor einem privaten Feld entfernt mit Field.setAccessible(true), es gelesen und kehrte das Feld in ursprünglichen Zustand mit Field.setAccessible(false).

+9

Sie können dies tun, aber das macht keinen Effekt, weil Sie nicht die Zugänglichkeit zu schützen, indem Sie es erneut auf false wie jeder Client kann jederzeit eine Feld-Instanz erhalten und verwenden Sie erneut setAccessible (true), um das Feld zu verwenden. Darüber hinaus ändert setAccessible weder die Zugänglichkeit des Feldes noch die Art der Nichtreflexion, so dass Sie es vor Clients schützen können, die das Feld nicht REFLECTION verwenden. – mickeymoon

+0

Einverstanden, aber wir müssen das immer tun. Niemand wird hier den "falschen" Wert übergeben. Warum also überhaupt eine zusätzliche Codezeile schreiben? – Dennis

14

Wahrscheinlich würden Sie nie setAccessible(false) in Ihrem gesamten Leben tun. Dies liegt daran, dass setAccessible nicht die Sichtbarkeit des a-Members dauerhaft ändert. Wenn Sie zu etwas wie method.setAccessible(true) sind, sind Sie erlaubt, nachfolgende Anrufe auf diesemethod Instanz auch wenn die Methode in der ursprünglichen Quelle ist private.

Zum Beispiel betrachten dies:

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

Danke für Ihre Antwort. –

+0

Gern geschehen :) – 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)); 

} 

} 
Verwandte Themen