How to access a field's value in an object using reflection

为君一笑 提交于 2019-12-04 14:59:36

问题


My Question: How to overcome an IllegalAccessException to access the value of an object's field using reflection.

Expansion: I'm trying to learn about reflection to make some of my projects more generic. I'm running into an IllegalAccessException when trying to call field.getValue(object) to get the value of that field in that object. I can get the name and type just fine.

If I change the declaration from private to public then this works fine. But in an effort to follow the "rules" of encapsulation I don't want to do this. Any help would be greatly appreciated! Thanks!

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

The Output:

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)

回答1:


Before you get a private field, you need to call setAccessible(true); on the corresponding field:

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:


By default you are not allowed to read non-public fields, but simply invoking field.setAccessible(true); will allow access. In other words, your code should say

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


来源:https://stackoverflow.com/questions/12784848/how-to-access-a-fields-value-in-an-object-using-reflection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!