使用反射获取字段值

问题描述 投票:0回答:5

我无法获取字段值。我想做的是在运行时获取对象。请让我知道我哪里出错了。

测试.类

import java.lang.reflect.Field;

public class Test {

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
        IllegalArgumentException, IllegalAccessException {

    final Field field = Class.forName("com.logging.EX").getDeclaredField("value");
    field.setAccessible(true);
    field.get(Class.forName("com.logging.EX"));
}

}

EX.班

public class EX {

private String value;


public EX(){
    value="data";
}
/**
 * @return the value
 */
public String getValue() {
    return value;
}

/**
 * @param value
 *            the value to set
 */
public void setValue(String value) {
    this.value = value;
}

}

java reflection
5个回答
16
投票

类似这样的事情...

import java.lang.reflect.Field;

public class Test {
    public static void main(String... args) {
        try {
            Foobar foobar = new Foobar("Peter");
            System.out.println("Name: " + foobar.getName());
            Class<?> clazz = Class.forName("com.csa.mdm.Foobar");
            System.out.println("Class: " + clazz);
            Field field = clazz.getDeclaredField("name");
            field.setAccessible(true);
            String value = (String) field.get(foobar);
            System.out.println("Value: " + value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Foobar {
    private final String name;

    public Foobar(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

或者,您可以使用类的

newInstance
方法在运行时获取对象的实例。不过,您仍然需要先设置该实例变量,否则它不会有任何值。

例如

Class<?> clazz = Class.forName("com.something.Foobar");
Object object = clazz.newInstance();

或者,它的构造函数中有两个参数,例如 String 和 int...

Class<?> clazz = Class.forName("com.something.Foobar");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("Meaning Of Life", 42);

或者您可以在运行时使用

clazz.getConstructors()

询问它的构造函数

NB 我故意省略了将此处创建的对象转换为预期的类型,因为这会破坏反射的意义,因为如果这样做,您已经知道该类,这将消除在中进行反射的需要第一名。


2
投票

您可以从类对象创建实例,并可在字段获取值中使用。

 Class modelClass = Class.forName("com.gati.stackoverflow.EX");
    final Field field = modelClass.getDeclaredField("value");
    field.setAccessible(true);
    Object modelInstance=modelClass.newInstance();
    field.get(modelInstance);

2
投票

所以,得到了以下答案。目前运行良好。不确定这是否是最好的选择。

您的测试课程:

public class Test {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException, InstantiationException {

        Field[] fields = Class.forName("com.logging.EX").newInstance().getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName() + " : " + field.get(Class.forName("com.logging.EX").newInstance()));
        }

    }
}

我通过调用

com.logging.EX
的实例将所有字段提取到数组中,然后循环遍历所有字段并提取字段保存的名称和值。此处尚未硬编码任何字段名称。

我的安全警告很少,因为我使用

private
访问修饰符访问变量,但它总是通过反射存在。 只是免责声明!

希望这有帮助!


1
投票

您需要 field.get() 上的 EX 实例。

final Field field = Class.forName("com.logging.EX").getDeclaredField("value");
field.setAccessible(true);
field.get(new EX());

0
投票

如果您使用 Spring,它有一个很好的“hasText”方法。 如果您需要检查至少一个字段不为空并且有文本(不为空),它可能看起来像这样(作为类方法)::

Stream.of(field1, field2,...fieldN).anyMatch(StringUtils::hasText);

© www.soinside.com 2019 - 2024. All rights reserved.