Java 反射通用获取字段值
我试图通过反射获得字段的值。问题是我不知道字段的类型,必须在获取值时确定它 此代码导致以下异常: 无法将java.lang.String字段com…fieldName设置为java.lang.StringJava 反射通用获取字段值,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(
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));
`