当前位置: 首页 > 知识库问答 >
问题:

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

壤驷喜
2023-03-14

我有一个方法,它返回字符串类型的字段对象列表。

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

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

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

共有1个答案

袁文景
2023-03-14

这可能是很多事情。如果在执行“get”或“set”时出现异常,可能是因为该字段是私有的。

你需要做...

field.setAccessible(true)

...在这种情况下,先于其他任何事情。

看起来您还想在方法所在的同一对象上调用“get”和“set”,因为您使用了“this”。。。

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

(你得到了一个IllegalArgumentException,因为看起来你得到了一种类型的类的字段,并且你试图对不同的类使用它们——例如这是一个实例的类)

如果你想让一个实用函数把一个特定对象的所有字符串字段都大写,你可以做如下的事情。在那之前,我建议这不是非常面向对象的,因为通过使用这样的反射,你打破了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());
        }
    }
}

注意:不适用于目标类中的静态字符串字段(您可能无论如何都不想更改这些字段)

 类似资料:
  • 问题内容: 我有一个方法: 当运行时,我得到如下输出: 现在我该怎样提取实际字符串值入, 使用反射? 问题答案: 看起来您需要引用该类的实例。您可能要调用get和pass的引用,将返回值转换为String。 您可以使用get,如下所示:

  • 问题内容: 我在Java中有一个对象(基本上是VO),但不知道其类型。 我需要获取在该对象中不为null的值。 如何才能做到这一点? 问题答案: 你可以用来获取该类的所有声明的字段。你可以用来获取价值。 简而言之: 要了解有关反射的更多信息,请查看有关该主题的Sun教程。 就是说,这些字段不一定全部代表VO的属性。你希望确定以或开头的公共方法,然后调用它以获取真实属性值。 也就是说,可能会有更优雅

  • 问题内容: 我在JPA中更新对象时遇到问题 我有豆子用户 和 当尝试更新时给我异常:当表评级包含行时,无法通过反射获得字段值 错误TransactionInterceptor:434-应用程序异常被提交异常com.vodafone.visradio.dataaccess.exception.DataAccessException覆盖:org.hibernate.PropertyAccessExce

  • 问题内容: 我试图通过反射接收字段值。问题是我不知道字段类型,必须在获取值时确定它。 这段代码会导致以下异常: 无法将java.lang.String字段com .... fieldName设置为java.lang.String 我尝试进行转换,但出现编译错误: 要么 我怎样才能做到这一点? 问题答案: 像之前回答的那样,你应该使用: 有时更喜欢的另一种方法是动态调用getter。示例代码: 还应

  • 问题内容: 我有以下实体: 还有以下EJB: 调用persist时,将引发具有以下根本原因的异常: 这是GlassFish 4.1的完整日志: 这是怎么引起的,我该如何解决? 问题答案: 我有同样的问题。这个错误似乎是从HB 4.3.6开始的,并且一直存在,我正在尝试4.3.10。具有相同的结果。 在我看来,访问实体字段的方式在HB 4.3.6+中已更改,可能与类加载器有关。在HB 4.3.6之前

  • 我知道如何计算出字符串中某个字符或数字的索引,但是有没有任何预定义的方法可以用来给我第n个位置的字符?所以在字符串“foo”中,如果我要求索引为0的字符,它会返回“f”。 注意——在上面的问题中,我所说的“字符”不是指字符数据类型,而是字符串中的字母或数字。这里重要的一点是,调用该方法时,我不会收到char,而是一个字符串(长度为1)。我知道substring()方法,但我想知道是否有更简洁的方法