如何在Java中循环访问类属性?

2022-08-31 10:07:45

如何在java中动态循环访问类属性。

例如:

public class MyClass{
    private type1 att1;
    private type2 att2;
    ...

    public void function(){
        for(var in MyClass.Attributes){
            System.out.println(var.class);
        }
    }
}

这在Java中可能吗?


答案 1

没有语言支持来做你要求的事情。

您可以使用反射在运行时反射(例如,使用Class.getDeclaredFields()获取Field数组)以反射方式访问类型的成员,但根据您尝试执行的操作,这可能不是最佳解决方案。

另请参见

相关问题


下面是一个简单的示例,仅显示反射能够执行的部分操作。

import java.lang.reflect.*;

public class DumpFields {
    public static void main(String[] args) {
        inspect(String.class);
    }
    static <T> void inspect(Class<T> klazz) {
        Field[] fields = klazz.getDeclaredFields();
        System.out.printf("%d fields:%n", fields.length);
        for (Field field : fields) {
            System.out.printf("%s %s %s%n",
                Modifier.toString(field.getModifiers()),
                field.getType().getSimpleName(),
                field.getName()
            );
        }
    }
}

上面的代码片段使用反射来检查 的所有声明字段;它产生以下输出:class String

7 fields:
private final char[] value
private final int offset
private final int count
private int hash
private static final long serialVersionUID
private static final ObjectStreamField[] serialPersistentFields
public static final Comparator CASE_INSENSITIVE_ORDER

有效的 Java 第 2 版,第 53 项:首选接口而不是反射

以下是本书的摘录:

给定一个 Class 对象,您可以获取表示类的构造函数方法字段的构造函数、方法和字段实例。[它们] 允许您以反射方式操作它们的基础对应项。然而,这种力量是有代价的:

  • 您将失去编译时检查的所有好处。
  • 执行反射访问所需的代码既笨拙又冗长。
  • 性能受到影响。

通常,不应在运行时在正常应用程序中以反射方式访问对象。

有一些复杂的应用程序需要反射。示例包括 [...故意省略...]如果您对应用程序是否属于这些类别之一有任何疑问,则可能不有疑问。


答案 2

在java中,直接访问字段并不是很好的风格。我建议为bean的字段创建getter和setter方法,然后使用java.beans包中的Introspector和BeanInfo类。

MyBean bean = new MyBean();
BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class);
for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) {
    String propertyName = propertyDesc.getName();
    Object value = propertyDesc.getReadMethod().invoke(bean);
}

推荐