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循环的第一行写过,但仍然给我相同的错误。查看我的更新代码。。