我想以下列方式迭代类字段
我有课
public class Parent{
String name;
String lastName;
}
public class Child extends Parent{
int childNumber;
}
父类中的我想要一个“获取”方法
孩子将继承
此方法将按名称
返回字段的值我如何检索该字段的值?
我希望方法是这样的:
public Object get(String key){
Field field;
Object result = null;
try {
field = this.getClass().getDeclaredField(key);
if(field!=null) {
field.setAccessible(true);
}
result = field.get(this); // this is where my problem, i don't know how to retrieve the field's value
} catch (NoSuchFieldException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
堆栈跟踪
java.lang.IllegalArgumentException: Can not set int field com.database.User.userID to java.lang.String
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(Unknown Source)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(Unknown Source)
at java.lang.reflect.Field.get(Unknown Source)
at com.database.DatabaseObject.get(DatabaseObject.java:106)
at com.database.DatabaseObject.set(DatabaseObject.java:128)
at com.database.DatabaseObject.getInsertPreparedStatement(DatabaseObject.java:64)
at com.database.Database.insert(Database.java:95)
at com.lenabru.webservice.ElectronicArenaWebService.register(ElectronicArenaWebService.java:21)
at com.database.Main.main(Main.java:29)
答案 0 :(得分:1)
要获得此堆栈跟踪,您必须将字符串值传递给field.get
,而不是this
。进行全面重建并再次测试。
以下是来自UnsafeFieldAccessorImpl
类的相关方法,正如您所看到的,如果您尝试传入String而不是可从类中分配的对象,则只能获取给定的,令人困惑的错误消息。声明字段:
protected void ensureObj(Object o) {
// NOTE: will throw NullPointerException, as specified, if o is null
if (!field.getDeclaringClass().isAssignableFrom(o.getClass())) {
throwSetIllegalArgumentException(o);
}
}
protected void throwSetIllegalArgumentException(Object o) {
throwSetIllegalArgumentException(o != null ? o.getClass().getName() : "", "");
}
protected void throwSetIllegalArgumentException(String attemptedType,
String attemptedValue) {
throw new IllegalArgumentException(getSetMessage(attemptedType,attemptedValue));
}
protected String getSetMessage(String attemptedType, String attemptedValue) {
String err = "Can not set";
if (Modifier.isStatic(field.getModifiers()))
err += " static";
if (isFinal)
err += " final";
err += " " + field.getType().getName() + " field " + getQualifiedFieldName() + " to ";
if (attemptedValue.length() > 0) {
err += "(" + attemptedType + ")" + attemptedValue;
} else {
if (attemptedType.length() > 0)
err += attemptedType;
else
err += "null value";
}
return err;
}
答案 1 :(得分:1)
我建议你做两件事之一:
如果您的真实代码的字段数与此处显示的示例相同,请为每个字段添加getXxx()
方法。例如,Parent
应该有getName()
(这应该是getFirstName()
?)和getLastName()
方法,Child
应该有getChildNumber()
。
如果您的代码比此更复杂,请使用Map
并通过委派给get()
来实施set()
和Map
方法。
反射适用于构建复杂工具的程序员,这些工具需要以非常低的级别操作对象。对于我们其他人来说,通常有更好的解决方案。
答案 2 :(得分:0)
如果您想要访问bean字段,可能是BeanUtils
中使用commons-beanutils
的最简单方法:
System.out.println(BeanUtils.getProperty(child, "name")); // get value from property
BeanUtils.setProperty(c, "lastName", "Ivan Ivanov"); // set value to property