2012-10-08 14 views
35

Meine Frage: Wie Sie eine IllegalAccessException überwinden, um den Wert eines Objekts Feld durch Reflexion zugreifen.Wie Zugriff auf den Wert eines Feldes in einem Objekt mit Hilfe der Reflektion

Erweiterung: Ich versuche über Reflexion zu lernen, um einige meiner Projekte generischer zu machen. Ich renne in eine IllegalAccessException beim Versuch, field.getValue(object) aufrufen, um den Wert dieses Feldes in diesem Objekt zu erhalten. Ich kann den Namen bekommen und gut tippen.

Wenn ich die Deklaration von private zu public ändern, dann funktioniert das gut. Aber im Bemühen, den "Regeln" der Kapselung zu folgen, möchte ich das nicht tun. Jede Hilfe würde sehr geschätzt werden! Vielen Dank!

Mein Code:

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

Der Ausgang:

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) sagen,' –

+1

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

Antwort

77

Bevor Sie get ein privates Feld, müssen Sie setAccessible(true); auf das entsprechende Feld nennen:

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

Dank! Wie wahr in der Tat. –

14

Standardmäßig ist es nicht erlaubt, nicht-öffentliche Felder zu lesen, aber das einfache Aufrufen von field.setAccessible(true); erlaubt den Zugriff. Mit anderen Worten, sollte Ihr Code

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