如何通过反射获取字符串字段值?
How to get a string field value via reflection?
我有这个方法 returns 字符串类型的字段对象列表。
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:在真实代码中 "someClass.class" 被设置为真实的 class 名称...)
生成的错误是 field.get(this) 方法中的 IllegalArgumentException(在 field.set 方法中)。
这可能涉及很多方面。如果您在执行 "get" 或 "set" 时遇到异常,可能是因为该字段是私有的。
你需要做...
field.setAccessible(true)
...在那种情况下先行。
您似乎还想在方法所在的同一对象上调用 "get" 和 "set",因为您使用了 "this"...
field.set(this, field.get(this).toString().toUpperCase());
(你得到一个 IllegalArgumentException 因为它看起来你有一种类型的 class 的字段并且你正试图将它们用于不同的 class - 例如 class this 是)
的一个实例
如果你想要一个实用函数将特定对象的所有字符串字段大写,你可以像下面这样做。不过,在此之前,我建议这不是非常面向对象的,因为通过像这样使用反射,您正在破坏 OOP 的 "encapsulation" 原则...
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());
}
}
}
注意:不适用于目标中的静态字符串字段 class(您可能无论如何都不想更改它们...)
我有这个方法 returns 字符串类型的字段对象列表。
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:在真实代码中 "someClass.class" 被设置为真实的 class 名称...)
生成的错误是 field.get(this) 方法中的 IllegalArgumentException(在 field.set 方法中)。
这可能涉及很多方面。如果您在执行 "get" 或 "set" 时遇到异常,可能是因为该字段是私有的。
你需要做...
field.setAccessible(true)
...在那种情况下先行。
您似乎还想在方法所在的同一对象上调用 "get" 和 "set",因为您使用了 "this"...
field.set(this, field.get(this).toString().toUpperCase());
(你得到一个 IllegalArgumentException 因为它看起来你有一种类型的 class 的字段并且你正试图将它们用于不同的 class - 例如 class this 是)
的一个实例如果你想要一个实用函数将特定对象的所有字符串字段大写,你可以像下面这样做。不过,在此之前,我建议这不是非常面向对象的,因为通过像这样使用反射,您正在破坏 OOP 的 "encapsulation" 原则...
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());
}
}
}
注意:不适用于目标中的静态字符串字段 class(您可能无论如何都不想更改它们...)