如何在Java反射中避免魔术字符串

时间:2014-05-20 10:41:17

标签: java reflection

我的应用程序中有以下代码:

for(PropertyDescriptor property : myObjectProperties){
    if(property.getName().equals("myPropertyName")){
         // logic goes here
    }
}

这在多个级别上当然是危险的,可能最糟糕的是,如果我在“MyObject”上重命名属性“myPropertyName”,代码将会中断。

那就是说,我最简单的方法是引用属性的名称而不明确地输入它(因为这会让我得到编译器警告)?我看起来像:

for(PropertyDescriptor property : myObjectProperties){
    if(property.getName().equals(MyObject.myPropertyName.getPropertyName())){
         // logic goes here
    }
}

或者甚至可以使用Java吗?

2 个答案:

答案 0 :(得分:3)

您可以通过向其添加一些注释来定义目标属性。然后在循环搜索具有所需注释的字段中。

首先定义一个可在运行时访问的注释

@Retention(RetentionPolicy.RUNTIME)
public @interface Target {
}

美好而轻松, 现在创建使用它的类

public class PropertySearcher {

    int awesome;
    int cool;
    @Target
    int foo;
    int bar;
    String something;
}

现在可以搜索它

public static void main(String[] args) {
    PropertySearcher ps = new PropertySearcher();
    for (Field f : ps.getClass().getDeclaredFields()) {

        for (Annotation a : f.getDeclaredAnnotations()) {
            if (a.annotationType().getName().equals(Target.class.getName())) {
                System.out.println("Fname= " + f.toGenericString());
                //do magic here
            }
        }
    }
}

输出 Fname= int reflection.PropertySearcher.foo 找到物业。

通过这种方式,您可以毫无后顾之忧地重构代码。

答案 1 :(得分:1)

由于多个字段可以等于同一个对象,因此无法从对象获取字段的声明名称。它在这里解释得更好:Is it possible to get the declaration name of an object at runtime in java?