我试图通过反射接收字段值。问题是我不知道字段类型,必须在获取值时决定它。
此代码会导致以下异常:
无法将java.lang.String字段com .... fieldName设置为java.lang.String
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Class<?> targetType = field.getType();
Object objectValue = targetType.newInstance();
Object value = field.get(objectValue);
我试图施放,但是我收到了编译错误:
field.get((targetType)objectValue)
或
targetType objectValue = targetType.newInstance();
我该怎么做?
答案 0 :(得分:122)
像之前的回答一样,你应该使用:
Object value = field.get(objectInstance);
有时候首选的另一种方法是动态调用getter。示例代码:
public static Object runGetter(Field field, BaseValidationObject o)
{
// MZ: Find the correct method
for (Method method : o.getMethods())
{
if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
{
if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
{
// MZ: Method found, run it
try
{
return method.invoke(o);
}
catch (IllegalAccessException e)
{
Logger.fatal("Could not determine method: " + method.getName());
}
catch (InvocationTargetException e)
{
Logger.fatal("Could not determine method: " + method.getName());
}
}
}
}
return null;
}
另请注意,当您的类继承自另一个类时,您需要以递归方式确定Field。例如,获取给定类的所有字段;
for (Class<?> c = someClass; c != null; c = c.getSuperclass())
{
Field[] fields = c.getDeclaredFields();
for (Field classField : fields)
{
result.add(classField);
}
}
答案 1 :(得分:96)
您应该将对象传递给字段的 get 方法,所以
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(object);
答案 2 :(得分:15)
我使用我的首选项类的toString()实现中的反射来查看类成员和值(简单和快速调试)。
我正在使用的简化代码:
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Class<?> thisClass = null;
try {
thisClass = Class.forName(this.getClass().getName());
Field[] aClassFields = thisClass.getDeclaredFields();
sb.append(this.getClass().getSimpleName() + " [ ");
for(Field f : aClassFields){
String fName = f.getName();
sb.append("(" + f.getType() + ") " + fName + " = " + f.get(this) + ", ");
}
sb.append("]");
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
我希望它会帮助某人,因为我也有搜索过。
答案 3 :(得分:10)
Integer typeValue = 0;
try {
Class<Types> types = Types.class;
java.lang.reflect.Field field = types.getDeclaredField("Type");
field.setAccessible(true);
Object value = field.get(types);
typeValue = (Integer) value;
} catch (Exception e) {
e.printStackTrace();
}
答案 4 :(得分:7)
虽然我不太清楚你想要实现什么,但我在你的代码中发现了一个明显的错误:
Field.get()
期望包含该字段的对象作为参数,而不是该字段的某些(可能)值。所以你应该有field.get(object)
。
由于您似乎在寻找字段值,因此您可以将其视为:
Object objectValue = field.get(object);
无需实例化字段类型并创建一些空/默认值;或许我错过了一些东西。
答案 5 :(得分:4)
你正在用错误的论点来调用。
应该是:
Object value = field.get(object);
答案 6 :(得分:1)
我将解决方案发布在Kotlin中,但它也可以与java对象一起使用。 我创建了一个功能扩展,以便任何对象都可以使用此功能。
fun Any.iterateOverComponents() {
val fields = this.javaClass.declaredFields
fields.forEachIndexed { i, field ->
fields[i].isAccessible = true
// get value of the fields
val value = fields[i].get(this)
// print result
Log.w("Msg", "Value of Field "
+ fields[i].name
+ " is " + value)
}}
看看这个网页:https://www.geeksforgeeks.org/field-get-method-in-java-with-examples/
答案 7 :(得分:1)
`
//Here is the example I used for get the field name also the field value
//Hope This will help to someone
TestModel model = new TestModel ("MyDate", "MyTime", "OUT");
//Get All the fields of the class
Field[] fields = model.getClass().getDeclaredFields();
//If the field is private make the field to accessible true
fields[0].setAccessible(true);
//Get the field name
System.out.println(fields[0].getName());
//Get the field value
System.out.println(fields[0].get(model));
`