Java 使用反射获取字段数据时出错

Java 使用反射获取字段数据时出错,java,spring-mvc,reflection,field,Java,Spring Mvc,Reflection,Field,我正在尝试使用反射获取字段名和字段值 我正在根据操作需要通过动态课程 我已经做了一个获取字段名和值的方法,我得到的是字段名,而不是字段值。 当我使用下面的代码时,它会给我一个错误java.lang.IllegalAccessException,说明无法访问类的私有成员 以下是我的更新的代码: public String SerializeCommand(ICommand command){ StringBuilder command_text = new StringBuilder()

我正在尝试使用反射获取字段名和字段值

我正在根据操作需要通过动态课程

我已经做了一个获取字段名和值的方法,我得到的是字段名,而不是字段值。 当我使用下面的代码时,它会给我一个错误
java.lang.IllegalAccessException
,说明无法访问类的私有成员

以下是我的
更新的
代码:

public String SerializeCommand(ICommand command){

    StringBuilder command_text = new StringBuilder();
    Field [] f = command.getClass().getDeclaredFields();
    for(Field field : f){
        field.setAccessible(true);
        command_text.append(field.getName() + ",");
        try {
            System.out.println(field.get(command.getClass()));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return command_text.toString();
}
这里ICommand是它的类名,假设操作是add,则将传递add class


你知道如何解决这个问题吗。

而不是command.getClass()传递command类的对象。值包含按对象而不是按类

Java还负责不能访问私有成员,即使是通过反射进行访问。但是构造函数、方法和字段都是s,它提供了一个方法来标记该成员为可访问的,尽管它可能是私有的:

field.setAccessible(true);
之后,您可以读取它,甚至可以在其上设置一个新值


编辑以使其清晰。考虑下面的简单记录类:

public class Record {
    private int length;
    private String name;
    public Record(int length, String name) {
        this.length = length;
        this.name = name;
    }
    public int getLength() { return length; }
    public String getName() { return name; }
}
现在让我们编写一个反射测试程序:

public class ReflectionTest {
    public static void main(String[] args) throws Exception {
        Record record = new Record(42, "42");
        Field[] fields = record.getClass().getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName() + " => " + field.get(record));
        }
    }
}
这将导致出现非法访问异常,因为无法访问专用字段。现在稍微更改foreach循环:

        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName() + " => " + field.get(record));
        }
这次您将看到预期的输出:

长度=>42

name=>42

您的错误还在于对类而不是对象调用get方法。这就像是一个小小的修改:

        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName() + " => " + field.get(record.getClass()));
        }
这次您将看到一个
IllegalArgumentException
(不是
IllegalAccessException
)。

请尝试此代码

public String SerializeCommand(ICommand command){

    StringBuilder command_text = new StringBuilder();
    Field [] f = command.getClass().getDeclaredFields();
    try{
    for(Field field : f){
        field.setAccessible(true);
        command_text.append(field.getName() + ",");
        System.out.println("Value :: " + field.get(command));
    }
    }catch(IllegalArgumentException e){
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return command_text.toString();
}

我无法创建该类的对象。这里ICommand是一个接口,我在每个类中实现它。我无法创建一个。好吧,但没有对象,你怎么能期望值?无论如何,您必须获取对象才能获取值。使用ICommand子类的对象来代替ICommand。但是如何创建ICommand子类的对象,我不能,因为类是在运行时加载的。那么怎么做呢?有什么想法吗?不确定在运行时将加载哪个类。您可以试试这个System.out.println(“Value::”+field.get(command));如果字段为私有使用字段.setAccessible(true);在获取值之前。在不运行应用程序的情况下,它会给我相同的错误,
IllegalAccessException
要访问该类的数据,我必须公开所有字段吗?你是什么意思?我描述了一个解决方案,你如何访问字段,即使它们是私有的。但它仍然会给我同样的错误
IllegalAccessException
,而不运行代码。如果你在调用get()或getName()或任何其他内容之前将字段设置为可访问,它就会工作。因此,语句“field.setAccessible(true);”必须是foreach循环中的第一条语句。是的,我在for循环的第一行写过,但仍然给我相同的错误。查看我的更新代码。。