如何通过反射获取字符串字段值?

时间:2015-04-16 15:12:36

标签: java reflection

我有这个方法返回String类型的Fields对象列表。

    public static List<Field> getStringFields(Class<?> clazz) {
        List<Field> toReturn = new ArrayList<Field>();

        Field[] allFields = clazz.getDeclaredFields();

        for (Field f : allFields) {
            Class<?> type = f.getType();
            if (type == String.class) {
                stringFields.add(f);
            }
        }

        return stringFields;
    }

这个方法应该捕获所有字符串字段:

public void capitalizeStringFields() {
    List<Field> stringFieldsToCapitalize = Utils.getStringFields(someClass.class);
    try {
        for (Field field : stringFieldsToCapitalize) {
            field.set(this, field.get(this).toString().toUpperCase());
        }
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

问题是:&#34; field.set(...)&#34;不管用。它应该将值大写并将其设置为该字段的新值,但它不起作用......任何想法如何解决这个问题? (PS:在实际代码中,&#34; someClass.class&#34;被设置为真正的类名...)

在field.get(this)方法中生成的错误是IllegalArgumentException(使用field.set方法)。

1 个答案:

答案 0 :(得分:2)

这可能是一些事情。如果您在执行&#34; get&#34;时遇到异常或&#34;设置&#34;,可能是因为该字段是私有的。

你需要......

field.setAccessible(true)

......在那种情况下的其他事情之前。

看起来你也想打电话给#34;得到&#34;和&#34;设置&#34;在与方法相同的对象上,因为你使用了&#34;这个&#34; ...

field.set(this, field.get(this).toString().toUpperCase());

(你得到一个IllegalArgumentException,因为它看起来你已经有了一种类的字段,并且你试图将它们用于另一个类 - 例如 this 是一个实例的类的)

如果你想要一个实用程序函数来大写特定对象的所有String字段,你可以在下面做这样的事情。在此之前,我建议这不是面向对象的,因为通过使用这样的反射,你正在破坏&#34;封装&#34; OOP的原则......

class Utils {
    public static List<Field> getStringFields(Class<?> clazz) { ... }

    public static void capitaliseEverythingInADodgyNonOOPWay(Object changeMe) {
        for(Field field : getStringFields(changeMe.getClass())) {
            // Add try catch etc...
            field.setAccessible(true);
            field.set(changeMe, field.get(changeMe).toString().toUpperCase());
        }
    }
}

注意:不能使用目标类中的静态字符串字段(你可能不会想要改变它们......)