从未知类获取数据的首选方法是什么

时间:2013-08-14 06:14:07

标签: java reflection

data是Class MyType的ArrayList,如果仅使用field.get(object),则代码不会编译说未处理的异常。 当我运行它时,我无法访问私人成员。然后我将MyType的所有成员字段更改为public。然后这段代码可行。但肯定有更好的获取数据的方法吗?

for (Object object : data)//get one object
    {
        ArrayList<Field> fields = 
                new ArrayList<Field>(Arrays.asList(object.getClass().getDeclaredFields()));//get all its fields
        for(Field field : fields)
            {
            try {
                System.out.println(field.get(object));//print its fields value
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            }

    }

3 个答案:

答案 0 :(得分:2)

使用Field.setAccessible(true)允许访问私有字段。

try {
       field.setAccessible(true);    
       System.out.println(field.get(object));//print its fields value
     } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
                e.printStackTrace();
     }

答案 1 :(得分:1)

最干净的方法是创建一个接口并从中派生出来或从一个抽象的超类派生。在这两种情况下,编译器都知道构造。 您可以通过以下代码获得带反射的单个字段:

Method.class.getDeclaredField(name)

答案 2 :(得分:0)

您可以使用setAccessible(boolean)FieldMethod上的Constructor来访问调用者通常无法访问的非公开成员。这样做可以消除您的错误。

更标准化的方法是使用introspection。如果该类遵循JavaBean约定,那么您可以使用IntrospectorBeanInfo来获取PropertyDescriptor实例,这使您可以访问bean的公共读写方法(getter和setter) 。例如,这是一个示例bean:

public class JavaBean {

    private boolean valid;
    private String name;
    private String label;

    public boolean isValid() {
        return valid;
    }

    public String getName() {
        return name;
    }

    public String getLabel() {
        return label;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}

在此,我们声明了validnamelabel属性。请注意,字段名称不用于确定属性的名称。相反,使用了get / isset方法。另请注意,原始boolean属性使用is作为getter前缀。

然后使用内省:

Object unknownType = new JavaBean();
BeanInfo javaBeanInfo = Introspector.getBeanInfo(JavaBean.class);
for (PropertyDescriptor property : javaBeanInfo.getPropertyDescriptors()) {
    System.out.println(property.getName());
}

这将打印(不一定按顺序):

class
valid
name
label

class位于此处,因为所有类都存在getClass()方法,因此class被视为属性。

然后,您可以使用PropertyDescriptor.readMethodPropertyDescriptor.writeMethod分别获取作为getter和setter的Method个对象,然后使用Method.invoke来获取和设置属性使用通常的反射API的给定对象的值。 PropertyDescriptor还有一些其他信息,例如属性类型和属性名称。这是直接使用反射的替代方法。它还允许其他人覆盖BeanInfo返回的Introspector作为自定义实现。