如何获取对实例变量的引用?

时间:2014-02-20 10:22:57

标签: java reflection

我有以下代码来获取类实例变量的值。

public void printFields(Object obj) throws Exception {
    Class<?> objClass = obj.getClass();

    Field[] fields = objClass.getFields();
    for(Field field : fields) {
        String name = field.getName();
        Object value = field.get(obj);

        System.out.println(name + ": " + value.toString());
    }
}

让我们说类A,类型为ArrayList。看起来像:

class A
{
   private ArrayList list;
}

现在我想获得对此类型list的引用。有可能吗?

因此,一旦我获得了引用,ArrayList中可用的所有方法都应该是可访问的。

怎么做?

5 个答案:

答案 0 :(得分:1)

您可以通过以下方式从Field实例获取值

  1. 使用AccessibleObject#setAccessible(boolean b)方法将字段设置为 accessible (在Field类中实现)。
  2. 通过Field#get(Object obj)方法获取其值。
  3. 例如:

    for (Field f : fields) {
        f.setAccessible(true);
        ArrayList value = (ArrayList) f.get(objClass);
    }
    

答案 1 :(得分:1)

您可以使用field.setAccessible(true);来规避封装。这并不一定总是有效:可能会抛出SecurityException

更好(如果你拥有类),设置成员public并完成它:

class A
{
   public ArrayList list;
}

至少那时您的使用模式是预期

获得list后,您可以使用该列表中的所有公开方法和字段。

答案 2 :(得分:1)

试试这个。

public ArrayList getField(A obj) throws Exception{
    Class c = obj.getClass();
    Field f = c.getDeclaredField("list");
    f.setAccessible(true);
    ArrayList lst = (ArrayList)f.get(obj);
    return lst;
}

答案 3 :(得分:0)

  1. 如果要获取在实例类中声明的所有字段(不仅是公共字段),则需要使用getDeclaredFields()而不是getFields()

  2. 此外,如果您想要访问私有字段的值,则需要使用true将其辅助功能设置为field.setAccessible(true)

答案 4 :(得分:0)

是的,你可以这样做。对于非公共字段,您必须使用field.getDeclaredField()方法。 如果要为该字段设置或读取值,则必须使用field.setAccessible(true)。 将value.toString()用于空字段时要小心NPE。

public static void printFields(Object obj) throws Exception {
    Class<?> objClass = obj.getClass();

    Field[] fields = objClass.getDeclaredFields();
    for(Field field : fields) {
        field.setAccessible(true);
        String name = field.getName();
        Object value = field.get(obj);

        System.out.println(name + ": " + value);
    }
}