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

Juk*_*nen 5 java reflection

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

for(PropertyDescriptor property : myObjectProperties){
    if(property.getName().equals("myPropertyName")){
         // logic goes here
    }
}
Run Code Online (Sandbox Code Playgroud)

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

也就是说,在不显式键入属性的情况下引用属性名称的最简单方法是什么(因为这将使我得到编译器警告)?我看起来像:

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

还是Java甚至有可能?

T.G*_*T.G 3

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

首先定义一个注释,该注释将在运行时访问

@Retention(RetentionPolicy.RUNTIME)
public @interface Target {
}
Run Code Online (Sandbox Code Playgroud)

很好又简单,现在创建使用它的类

public class PropertySearcher {

    int awesome;
    int cool;
    @Target
    int foo;
    int bar;
    String something;
}
Run Code Online (Sandbox Code Playgroud)

现在让我们搜索它

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

找到输出 Fname= int reflection.PropertySearcher.foo 属性。

这样你就可以毫无顾虑地重构你的代码。