Java 反射通用获取字段值

Java 反射通用获取字段值,java,reflection,Java,Reflection,我试图通过反射获得字段的值。问题是我不知道字段的类型,必须在获取值时确定它 此代码导致以下异常: 无法将java.lang.String字段com…fieldName设置为java.lang.String Field-Field=object.getClass().getDeclaredField(fieldName); 字段。setAccessible(true); 类targetType=field.getType(); objectValue=targetType.newInstance(

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

此代码导致以下异常:

无法将java.lang.String字段com…fieldName设置为java.lang.String

Field-Field=object.getClass().getDeclaredField(fieldName);
字段。setAccessible(true);
类targetType=field.getType();
objectValue=targetType.newInstance();
Object value=field.get(objectValue);
我试图强制转换,但出现编译错误:

field.get((targetType)objectValue)


我如何才能做到这一点?

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

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

Object objectValue = 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;
}
还要注意,当您的类从另一个类继承时,您需要递归地确定字段。例如,获取给定类的所有字段

    for (Class<?> c = someClass; c != null; c = c.getSuperclass())
    {
        Field[] fields = c.getDeclaredFields();
        for (Field classField : fields)
        {
            result.add(classField);
        }
    }
for(类c=someClass;c!=null;c=c.getSuperclass())
{
Field[]fields=c.getDeclaredFields();
用于(字段类字段:字段)
{
结果.添加(类字段);
}
}

我使用首选项类的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();
}
@覆盖
公共字符串toString(){
StringBuilder sb=新的StringBuilder();
类thisClass=null;
试一试{
thisClass=Class.forName(this.getClass().getName());
Field[]aClassFields=thisClass.getDeclaredFields();
sb.append(this.getClass().getSimpleName()+“[”);
用于(字段f:aClassFields){
字符串fName=f.getName();
sb.append(“+f.getType()+”)+fName+“=”+f.get(this)+“,”);
}
某人加上(“]”);
}捕获(例外e){
e、 printStackTrace();
}
使某人返回字符串();
}
我希望它能帮助一些人,因为我也搜索过;
 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();
 }
试一试{ 类类型=types.Class; java.lang.reflect.Field=types.getDeclaredField(“Type”); 字段。setAccessible(true); 对象值=field.get(类型); typeValue=(整型)值; }捕获(例外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)
}}

查看此网页:

查看,
字段的参数。get()
应该是
对象
,而不是
对象值
。您自己需要迭代超类似乎并不完全正确。c.getFields()或c.getField()将自动搜索每个实现接口上的字段,并递归搜索所有超类。因此,从getDeclaredX切换到getX就足够了。事实上,getFields()例程将允许您获取所有超类和接口的字段,但只获取公共类和接口的字段。通常,字段是私有的/受保护的,并通过getter/setter公开。@Marius,我可以知道什么是包是
BaseValidationObject
?@Marius
对象
类没有方法
getMethods()
。有什么建议吗?
object
在第一个代码段中没有定义,读者无法理解如何使用它。您知道为什么必须在field中使用object。get(object)——field本身来自该对象,为什么它再次需要它@serup否,Field对象来自Class对象,它与实际实例没有连接。(
object.getClass()
将返回此类对象)
代码段中的对象
未定义,因此读者无法理解如何使用它。@RajanPrasad不太清楚。问题中只有一个对象名为“object”。其他对象有其他名称。答案是精确的,并且是针对问题和问题中使用的名称量身定做的,以使事情尽可能清楚。如果它对你不起作用-我不知道如何让它更清晰,你应该尝试其他答案,或者可能暂时避免反思。向下投票。字段。获取(对象)未澄清。
对象
中需要传递什么?
对象
未定义,读者无法理解如何应用答案。
对象
未定义,读者无法理解如何在回答投票中应用示例。字段。获取(对象)未澄清。在
对象中需要传递什么?如果值不是整数类型怎么办?
 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();
 }
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)
}}
    ` 
//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));
`