2012-05-17 29 views
69

Używam niektórych adnotacji do dynamicznego ustawiania wartości pól w klasach. Ponieważ chcę to zrobić bez względu na to, czy jest to publiczne, chronione czy prywatne, jestem za każdym razem wywoływania obiektu Field, zanim wywołam metodę set(). Moje pytanie brzmi, jaki rodzaj wpływu ma wywołanie setAccessible() na samym polu?Odbicie Java - wpływ setAccessible (true)

Mówiąc dokładniej, jest to pole prywatne i ten zestaw wywołań kodowych setAccessible(true). Jeśli jakieś inne miejsce w kodzie było wtedy, aby odzyskać to samo pole przez odbicie, czy pole było już dostępne? A może metody getDeclaredFields() i getDeclaredField() zwracają za każdym razem nowe instancje obiektu Field?

Zgaduję, że innym sposobem wyrażenia pytania jest to, czy zadzwonię pod numer setAccessible(true), jak ważne jest przywrócenie pierwotnej wartości po zakończeniu?

Odpowiedz

52

Dlaczego nie spróbować samemu ;-)

public class FieldAccessible { 
    public static class MyClass { 
     private String theField; 
    } 

    public static void main(String[] args) throws Exception { 
     MyClass myClass = new MyClass(); 
     Field field1 = myClass.getClass().getDeclaredField("theField"); 
     field1.setAccessible(true); 
     System.out.println(field1.get(myClass)); 
     Field field2 = myClass.getClass().getDeclaredField("theField"); 
     System.out.println(field2.get(myClass)); 
    } 

} 

więc odpowiedzieć na pytanie: z setAccessible() zmienić zachowanie AccessibleObject, czyli np Field, ale nie rzeczywiste Dziedzina klasa. Oto documentation (fragment):

Wartość true wskazuje, że odbicie obiekt powinien tłumić sprawdzanie dostępu język Java, gdy jest używany

+9

Ponieważ jestem leniwy, i pomyślałem, kogoś już znałem odpowiedź z samej głowy. :) Dzięki za informację. – dnc253

+27

... i dlatego, że sam testowanie oznacza, że ​​wiesz o konkretnej implementacji, ale to nie oznacza, że ​​testowane zachowanie wynikowe jest poprawne. :) – Devolus

+3

"Dlaczego sam nie spróbujesz?" nie jest odpowiednią krytyką pytania Stack Overflow. Ta strona internetowa jest bazą wiedzy. Takie są właśnie takie pytania. –

25

Metoda musi zawsze zwracać nowy obiekt, ponieważ obiekt ten ma zmienną flagę . Nie ma potrzeby resetowania flagi. Pełne informacje można znaleźć w this blog post.

0
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)); 
    } 

}