如何在java中动态读取对象属性?

时间:2011-10-12 20:29:06

标签: java object core

有没有办法动态地读取和打印对象属性(Java)?例如,如果我有以下对象

public class A{
  int age ;
  String name;
  float income;

}

public class B{
 int age;
 String name;
}

public class mainA{
   A obj1 = new A();
   method(A);
   method(B); 
}

the output should be like

While running method(A):
Attribute of Object are age,name,income;
While executing method(B):
Attribute of Objects are age,name;

我的问题是我可以在method()中传递各种对象,有没有办法可以访问不同对象的属性。

5 个答案:

答案 0 :(得分:15)

您想使用The Reflection API。具体来说,请查看discovering class members

您可以执行以下操作:

public void showFields(Object o) {
   Class<?> clazz = o.getClass();

   for(Field field : clazz.getDeclaredFields()) {
       //you can also use .toGenericString() instead of .getName(). This will
       //give you the type information as well.

       System.out.println(field.getName());
   }
}

我只是想添加一个注意事项,你通常不需要做这样的事情,对于你可能不应该的大多数事情。反射可以使代码难以维护和阅读。当然,有些特殊情况需要使用Reflection,但那些相对较少。

答案 1 :(得分:3)

使用org.apache.commons.beanutils.PropertyUtils我们可以做到这一点。如果为bean定义了正确的getter和setter,我们也可以动态设置值:

import org.apache.commons.beanutils.PropertyUtils;
import java.beans.PropertyDescriptor;

public class PropertyDescriptorTest {

    public static void main(String[] args) {

        // Declaring and setting values on the object
        AnyObject anObject = new AnyObject();
        anObject.setIntProperty(1);
        anObject.setLongProperty(234L);
        anObject.setStrProperty("string value");

        // Getting the PropertyDescriptors for the object
        PropertyDescriptor[] objDescriptors = PropertyUtils.getPropertyDescriptors(anObject);

        // Iterating through each of the PropertyDescriptors
        for (PropertyDescriptor objDescriptor : objDescriptors) {
            try {
                String propertyName = objDescriptor.getName();
                Object propType = PropertyUtils.getPropertyType(anObject, propertyName);
                Object propValue = PropertyUtils.getProperty(anObject, propertyName);

                // Printing the details
                System.out.println("Property="+propertyName+", Type="+propType+", Value="+propValue);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

}

设置特定属性的值:

// Here we have to make sure the value is
// of the same type as propertyName
PropertyUtils.setProperty(anObject, propertyName, value);

输出将是:

Property=class, Type=class java.lang.Class, Value=class genericTester.AnyObject
Property=intProperty, Type=int, Value=1
Property=longProperty, Type=class java.lang.Long, Value=234
Property=strProperty, Type=class java.lang.String, Value=string value

答案 2 :(得分:2)

您可以使用反射来获取对象中的每个字段(如果安全配置允许)。

如果你不是为了自我教育而需要它,那么使用Apache Commons的ReflectionUtils可能是值得的。

答案 3 :(得分:1)

您可以使用反射,但API使用效果不是很好。但是你要做的事情根本不是面向对象的。 A和B应该有“打印自己”的方法,它会输出它们的值(你应该在超类/接口中指定方法来使用多态来调用方法)。

答案 4 :(得分:0)

我想我会考虑采用不同的方法。

如果你真的想把这些视为数据,那么有什么理由他们不能成为哈希表(他们有相关的代码吗?)

反思会做到这一点,但这是最后的手段 - 在进行反思之前,你应该认真考虑不同的方法。

必须访问存在的变量的情况 - 如数据库映射(Hibernate)和注入​​(Spring)。您可能想要考虑这样的打包解决方案是否符合您的需求,以便未来的程序员可以在不了解您的特定解决方案的情况下了解您的操作。

此外,Spring注入可以做一些可能符合您需求的事情。

另外,如果您打算使用反射,请认真考虑注释,这样您就不会将功能与简单的任意属性名称联系起来。