【问题标题】:how to get field value of a field in this class如何获取此类中字段的字段值
【发布时间】:2013-08-17 18:18:29
【问题描述】:

我想通过以下方式遍历类字段

我有课

public class Parent{

String name;
String lastName;

}

public class Child extends Parent{

int childNumber;
}

在父类中我想要一个“get”方法

孩子会继承

此方法将按名称返回字段的值

我如何检索字段的值?

我希望方法是这样的:

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)

【问题讨论】:

  • 您提供的代码 sn-p 有什么问题?
  • 我将堆栈跟踪放在帖子中,java 认为我正在尝试设置字段,但没有得到它
  • 您能否展示一下您是如何使用该代码的? (this 指的是什么以及您尝试访问的字段的名称?)

标签: java reflection field


【解决方案1】:

要获得此堆栈跟踪,您必须将字符串值传递给field.get,而不是this。进行完全重建并再次测试。

这里是来自UnsafeFieldAccessorImpl 类的相关方法,如您所见,如果您尝试传入字符串而不是可从该字段所在的类分配的对象,则只能得到给定的、令人困惑的错误消息声明:

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

【讨论】:

    【解决方案2】:

    我建议你做以下两件事之一:

    1. 如果您的实际代码中的字段与此处显示的示例一样少,请为每个字段添加一个getXxx() 方法。例如,Parent 应该有getName()(应该是getFirstName()?)和getLastName() 方法和Child 应该有getChildNumber()

    2. 如果您的代码比这更复杂,请使用Map 并通过委托给Map 来实现get()set() 方法。

    Reflection 适用于构建需要在非常低级别操作对象的复杂工具的程序员。对于我们其他人来说,通常有更好的解决方案。

    【讨论】:

      【解决方案3】:

      如果您想访问 bean 字段,这可能是使用 commons-beanutils 中的 BeanUtils 的最简单方法:

      System.out.println(BeanUtils.getProperty(child, "name")); // get value from property
      
      BeanUtils.setProperty(c, "lastName", "Ivan Ivanov"); // set value to property
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-02
        • 1970-01-01
        相关资源
        最近更新 更多