2012-05-17 12 views
69

Estoy usando algunas anotaciones para establecer dinámicamente valores de campos en clases. Como quiero hacer esto independientemente de si es público, protegido o privado, llamo al setAccessible(true) en el objeto Field cada vez antes de llamar al método set(). Mi pregunta es ¿qué tipo de impacto tiene la llamada setAccessible() en el campo mismo?Reflejo de Java: impacto de setAccessible (verdadero)

Más específicamente, supongamos que es un campo privado y este conjunto de códigos llama al setAccessible(true). Si algún otro lugar en el código fuera recuperar el mismo campo a través de la reflexión, ¿el campo ya estaría accesible? ¿O los métodos getDeclaredFields() y getDeclaredField() devuelven nuevas instancias de un objeto Field cada vez?

Supongo que otra forma de plantear la pregunta es si llamo al setAccessible(true), ¿qué importancia tiene volver al valor original una vez que haya terminado?

Respuesta

52

Por qué no tratas de usted mismo ;-)

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

} 

Así que para responder a su pregunta: con setAccessible() cambia el comportamiento de la AccessibleObject, es decir, el Field ejemplo, pero no el campo real de la clase. Aquí está la documentation (extracto):

Un valor de true indica que el objeto reflejado debe suprimir la comprobación de acceso lenguaje Java cuando se utiliza

+9

Como soy vago, y pensé que alguien Ya sabía la respuesta de la parte superior de su cabeza. :) Gracias por la info. – dnc253

+27

... y porque probarse significa que usted conoce su implementación particular, pero eso no significa necesariamente que el comportamiento resultante sea el correcto. :) – Devolus

+3

"¿Por qué no lo intentas tú mismo?" no es una crítica adecuada para una pregunta de desbordamiento de pila. Este sitio web es una base de conocimiento. Preguntas como esta son el punto. –

25

El método getDeclaredField tiene que devolver un nuevo objeto cada vez, exactamente porque este objeto tiene el indicador accessible mutable. Entonces no hay necesidad de reiniciar la bandera. Puede encontrar la información completa en 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)); 
    } 

} 
Cuestiones relacionadas