在获得成员变量的值中的Java与反射陷阱(Pitfalls in getting member va

2019-11-02 16:55发布

我有一个抽象类,如下所示。 我想成员变量的所有值。

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

这是我第一次与反射试验。 这是实现这一目标的正确方法是什么? 我想知道什么是在这种情况下,使用反射的陷阱。

Answer 1:

你的代码遍历静态和私人领域。 所以,你应该检查你遍历只有静态字段。

for (Field field : PARAMS.class.getFields()) {
    if (Modifiered.isStatic(field.getModifiers())) continue;
    String name = field.getName() ;
    String value = (String) field.get(PARAMS.class);
}

注: 为乔恩提到的,对于静态字段访问实例参数被忽略。 不过,我更喜欢传球的类,而不是零,因为这是缩进一个更好的文档。

然而,甚至是更好的做法,与注释来注释字段,以便你只得到你真正想要的其他程序员(或者甚至是幕后的Java语言)添加任何其他静态字段这些字段。 如果你这样做,你的代码看起来像

for (Field field : PARAMS.class.getFields()) {
    if (!field.isAnnotationsPresent(YourAnnotation.class)) continue;
    String name = field.getName() ;
    String value = (String) field.get(PARAMS.class);
}


Answer 2:

这不是很正确-的说法get最好应null的可读性的原因:这样的说法的一点是给它,当你检索实例字段的目标。

所以,你的代码可以只是:

Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
    String name = field.getName() ;
    String value = (String) field.get(null);
}

现在,这应该工作...但你会怎样使用这些值呢? 有你为什么要做到这一点,而不是创建一个不变的任何原因Map<String, String>直接暴露?

反思是得很好,这是必要的,但你有没有给予足够的信息,以确定它是否确实有必要在这种情况下。



Answer 3:

另外一个问题, getFields返回所有可用的字段这个类的(静态的或无意的)和它的所有超。 对你没有公布具体的代码,因为唯一的超类的问题是Object不具有公共领域。
我至少会测试如果该字段在正确的类中声明- getDeclaringClass() -如果它有正确的返回类型- getType()

使用注释,阿德里安建议,最好恕我直言。



文章来源: Pitfalls in getting member variable values in Java with reflection