反射泛型 get 字段值

我试图通过反思获得一个字段的价值。问题是我不知道字段的类型,必须在获取值的同时确定它。

这段代码导致了这个异常:

无法将 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();

我怎么能这么做?

460180 次浏览

尽管我不太清楚您想要实现什么目标,但我发现您的代码中有一个明显的错误: Field.get()期望将包含该字段的对象作为参数,而不是该字段的某个(可能的)值。所以你应该有 field.get(object)

由于您似乎正在查找字段值,因此可以通过以下方式获取该值:

Object objectValue = field.get(object);

不需要实例化字段类型并创建一些空/默认值; 或者我可能遗漏了什么。

您应该将 对象传递给 场地走开方法,因此

  Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(object);

你用错误的论点调用 get。

它应该是:

Object value = field.get(object);

如前所述,你应该使用:

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);
}
}

我使用首选项类的 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();
}

我希望它能帮到某人,因为我也找过了。

 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();
}

我在 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/

    `
//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));
`

能够使用以下方法访问类中的私有字段

 Beneficiary ben = new Beneficiary();//class with multiple fields
ben.setName("Ashok");//is set by a setter
                

//then to get that value following was the code which worked for me
Field[] fields = ben.getClass().getDeclaredFields();
    

for(Field field: fields) {
field.setAccessible(true);//to access private fields
System.out.println(field.get(ben));//to get value
//assign value for the same field.set(ben, "Y");//to set value
}