2012-10-08 56 views
35

Mi pregunta: Cómo superar un IllegalAccessException para acceder al valor del campo de un objeto utilizando la reflexión.Cómo acceder al valor de un campo en un objeto utilizando la reflexión

Expansión: Estoy tratando de aprender sobre la reflexión para hacer que algunos de mis proyectos sean más genéricos. Me encuentro con un IllegalAccessException al intentar llamar al field.getValue(object) para obtener el valor de ese campo en ese objeto. Puedo obtener el nombre y tipo bien.

Si cambio la declaración de private a public, entonces funciona bien. Pero en un esfuerzo por seguir las "reglas" de la encapsulación, no quiero hacer esto. ¡Cualquier ayuda sería muy apreciada! ¡Gracias!

Mi Código:

package main; 

import java.lang.reflect.Field; 

public class Tester { 

    public static void main(String args[]) throws Exception { 
    new Tester().reflectionTest(); 
    } 

    public void reflectionTest() throws Exception { 
    Person person = new Person("John Doe", "555-123-4567", "Rover"); 
    Field[] fields = person.getClass().getDeclaredFields(); 
    for (Field field : fields) { 
     System.out.println("Field Name: " + field.getName()); 
     System.out.println("Field Type: " + field.getType()); 
     System.out.println("Field Value: " + field.get(person)); 
     //The line above throws: Exception in thread "main" java.lang.IllegalAccessException: Class main.Tester can not access a member of class main.Tester$Person with modifiers "private final" 
    } 
    } 

    public class Person { 

    private final String name; 
    private final String phoneNumber; 
    private final String dogsName; 

    public Person(String name, String phoneNumber, String dogsName) { 
     this.name = name; 
     this.phoneNumber = phoneNumber; 
     this.dogsName = dogsName; 
    } 
    } 
} 

La salida:

run: 
Field Name: name 
Field Type: class java.lang.String 
Exception in thread "main" java.lang.IllegalAccessException: Class main.Tester can not access a member of class main.Tester$Person with modifiers "private final" 
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:95) 
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261) 
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253) 
    at java.lang.reflect.Field.doSecurityCheck(Field.java:983) 
    at java.lang.reflect.Field.getFieldAccessor(Field.java:927) 
    at java.lang.reflect.Field.get(Field.java:372) 
    at main.Tester.reflectionTest(Tester.java:17) 
    at main.Tester.main(Tester.java:8) 
Java Result: 1 
BUILD SUCCESSFUL (total time: 0 seconds) 
+10

'field.setAccessible (true);' –

+1

http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html – kosa

Respuesta

77

Antes get un campo privado, es necesario llamar setAccessible(true); en el campo correspondiente:

for (Field field : fields) { 
    field.setAccessible(true); //Additional line 
    System.out.println("Field Name: " + field.getName()); 
    System.out.println("Field Type: " + field.getType()); 
    System.out.println("Field Value: " + field.get(person)); 
} 
+2

Gracias! Cuán cierto de hecho. –

14

De manera predeterminada, no está permitido leer campos no públicos, pero simplemente invocando field.setAccessible(true); se permitirá el acceso. En otras palabras, el código debe decir

for (Field field : fields) { 
    field.setAccessible(true); 
    .... 
Cuestiones relacionadas