如何在没有硬编码名称的情况下引用方法和字段?

时间:2014-07-18 12:36:29

标签: java methods field

我需要在验证注册表对象中注册字段以供以后验证,它是这样的;

public class ValidationRegisterer{

    public void register(String spElPath, Validator validator){
        //puts spElPath and the related validator into a collection...
    }

}

假设我有A班;

public class A {
    private String name;

    public String getName(){
        return this.name;
    }
}

我想验证A对象的名称字段,然后我正在注册这样的Validator;

validationRegisterer.register("name", MandatoryFieldValidator.class);

validationRegisterer已设置为以root身份使用A类,因此它知道它应该查找一个类来获取“name”。为了检索值并注册验证器,我使用的是Spring Expression Language(SpEl)。

但是我不想在这个例子中硬编码像“name”这样的字段名称,因为有人可以在不改变注册路径的情况下进行重构并更改字段名称,在发生运行时异常之前我们无法检测到这一点。有没有办法存储字段名称和类方法的引用,如Hibernate Metadata Generated classes?

3 个答案:

答案 0 :(得分:2)

我建议你自己在分配字段的位置进行验证(即在构造函数和/或变量的set方法中)。

如果您不想手动验证,请查看反射。

使用注释标记字段以进行验证,而不是对字段名称进行硬编码。然后,使用反射来查找标记的字段。

enum ValidationType{
    NotNull,
    NotEmpty,
    NoDigits,
    NoLetters
}

@interface StringValidation {
    ValidationType validationType();
}

public class ValidationTest{
    @StringValidation(validationType = ValidationType.NotNull);
    String validateThisField;
}

在此示例中,您的反射代码需要搜索ValidationTest中的字段,检查StringValidation注释。如果注释存在,请查看ValidationType并执行所请求的验证。

答案 1 :(得分:0)

您可以使用java reflection API并调用Class#getDeclaredFields来检索类中的所有字段,迭代此方法返回的数组并调用寄存器并将其传递给Field#getName

for(Field field : getClass().getDeclaredFields()) {
    validationRegisterer.register(field.getName(), 
        MandatoryFieldValidator.class);
}

答案 2 :(得分:0)

如果你有Class对象或类的实例,你可以访问它的任何字段,如下所示:

String property = "lastName";
Field field = targetObject.getClass().getDeclaredField(property);
field.setAccessible(true); //overrides private
field.set(targetObject, value);

但您也可以使用http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getDeclaredFields()方法获取所有字段以接收其字段数组。

虽然我有点想知道你是否不能只使用Bean Validation API并使用Annotations进行配置。