2013-04-26 15 views
6

jestem bardzo nowy w refleksji i mam wątpliwości, jak:
Jaki jest powód metody setAccessible klasy AccessibleObject mają parametr boolowski?

public void setAccessible(boolean flag) throws SecurityException 

Metoda ta ma flagę boolen parametr, który wskazuje nowy dostępności wszelkich pól lub metod.
Na przykład, jeśli mamy próby uzyskania dostępu do private metodę klasy spoza klasy potem sprowadzić metodę używając getDeclaredMethod i ustawić dostęp jako true, więc może być wywołana, jak: method.setAccessible(true);
Teraz w których scenariusz powinniśmy użyć method.setAccessible(false);, na przykład można go użyć, gdy istnieje metoda public i ustawiamy dostępność jako false. Ale jaka jest tego potrzeba? Czy moje zrozumienie jest jasne?
Jeśli nie ma zastosowanie method.setAccessible(false) wtedy możemy zmienić podpis metody jak:

public void setAccessible() throws SecurityException 
+1

Nie chcesz opuścić kod pod odbicie w stanie, który programista kodu ** nie zamierzają ** . Czy ty ? Użyłeś refleksji do _unlock_ kawałka kodu do inspekcji, czy chcesz go później zostawić _unlocked_? –

+0

Yup. rozumiesz. –

+0

Downvoater, możesz dodać komentarz, aby poprawić moje pytanie .. –

Odpowiedz

5

scenariusz: usunięto ochronę przed prywatnym polu Field.setAccessible(true), czytać i wrócił boiska do stanu pierwotnego z Field.setAccessible(false).

+9

możesz to zrobić, ale to nie działa, ponieważ nie chronisz dostępu, ustawiając go ponownie na false, ponieważ każdy klient może w dowolnym momencie uzyskać instancję pola i ponownie użyj setAccessible (true), aby użyć pola. Co więcej, setAccessible nie zmienia na stałe dostępu do pola ani nie odbija się od niego, dzięki czemu można go chronić przed klientami używającymi pola w sposób inny niż REFLECTION. – mickeymoon

+0

Zgoda, ale zawsze musimy to robić. Nikt nie przekaże tutaj wartości "false". Dlaczego więc nawet zawracasz sobie głowę napisaniem dodatkowej linii kodu? – Dennis

14

Prawdopodobnie nigdy nie zrobiłbyś setAccessible(false) w całym swoim życiu. Dzieje się tak, ponieważ setAccessible nie zmienia trwale widoczności członka. Gdy masz coś w rodzaju method.setAccessible(true), możesz wykonywać kolejne wywołania na tej instancjimethod, nawet jeśli metoda z oryginalnego źródła to prywatna.

Na przykład rozważ to:

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

Dzięki za odpowiedź. –

+0

nie ma za co :) – 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)); 

} 

} 
Powiązane problemy