2012-10-08 28 views
35

我的問題:如何克服IllegalAccessException以使用反射訪問對象字段的值。如何使用反射訪問對象中某個對象的值

擴展:我想了解反射使我的一些項目更通用。當試圖呼叫field.getValue(object)以獲取該對象中該字段的值時,我遇到了IllegalAccessException。我可以得到名字和類型就好了。

如果我將聲明從private更改爲public,那麼這工作正常。但爲了遵循封裝的「規則」,我不想這樣做。任何幫助將不勝感激!謝謝!

我的代碼:

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

輸出:

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(真);' –

+1

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

回答

77

get私人領域之前,你需要調用setAccessible(true);上的相應字段:

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

謝謝!確實如此真實。 –

14

默認情況下,您不允許閱讀非公開字段,但僅調用field.setAccessible(true);將允許訪問。換句話說,你的代碼應該說

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