我有一个抽象类,如下所示。我想获得成员变量的所有值。
public abstract class PARAMS {
public static final String NAME1 = "VAL1";
public static final String NAME2 = "VAL2";
public static final String NAME3 = "VAL3";
}
使用反射检索值,如下所示。
Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
String name = field.getName() ;
String value = (String) field.get(name);
}
这是我第一次尝试反射。这是实现目标的正确方法吗?我想知道在这种情况下使用反射的缺陷是什么。
答案 0 :(得分:4)
您的代码遍历两个静态和私有字段。因此,您应该检查是否仅对静态字段进行迭代。
for (Field field : PARAMS.class.getFields()) {
if (Modifiered.isStatic(field.getModifiers())) continue;
String name = field.getName() ;
String value = (String) field.get(PARAMS.class);
}
NB:如Jon所述,对于静态字段访问,实例参数将被忽略。但是,我更喜欢传入类而不是null,因为这是更好的缩进文档。
然而,更好的做法是使用注释来注释您的字段,这样您才能获得那些您真正不希望其他程序员添加其他静态字段的字段(甚至是幕后的Java语言)。如果您这样做,您的代码将看起来像
for (Field field : PARAMS.class.getFields()) {
if (!field.isAnnotationsPresent(YourAnnotation.class)) continue;
String name = field.getName() ;
String value = (String) field.get(PARAMS.class);
}
答案 1 :(得分:3)
这不完全正确 - 为了便于阅读,get
的理论理论上应该是null
:该论点的目的是为它提供一个目标,用于检索实例字段。
所以你的代码可以只是:
Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
String name = field.getName() ;
String value = (String) field.get(null);
}
现在,这应该有效......但你对这些价值观做了什么?您是否有任何理由想要这样做而不是创建直接暴露的不可变Map<String, String>
?
在必要时反映很好,但是你没有提供足够的信息来确定这个案例中是否真的有必要。
答案 2 :(得分:0)
另一个问题,getFields
返回此类及其所有超类的所有可访问字段(静态或非静态)。对于您发布的特定代码而言,这不是问题,因为唯一的超类是Object
,没有公共字段
我至少会测试该字段是否在正确的类中声明 - getDeclaringClass()
- 如果它具有正确的返回类型 - getType()
。
正如阿德里安所说,使用注释是最好的恕我直言。