【问题标题】:Java custom annotation to find methods用于查找方法的 Java 自定义注解
【发布时间】:2015-05-25 17:31:38
【问题描述】:

我想创建注释(我可以为它设置某种id),我可以把它放在变量上,并编写方法,通过注释设置的id返回这个变量的getter或setter方法;

作为示例,我做了类似的事情,但仅用于方法,所以我需要两个注解用于 setter 和 getter 方法,或者向一个注解添加更多参数。也许可以为变量创建一个注释,然后找到我需要的方法(setter 或 getter)?

我做了什么:

注解类:

    public @interface FieldRawValue {

    String value() default "";
}

带有 getter 和 setter 的模型类(带有 getter 注释):

公共类 PajamuModel 扩展 AbstractModel{

private String id;
private String pajamuType;
private String pajamuSource;
private Date pajamuData;
private double pajamuSuma;
private String valiuta;
private String note;

@FieldRawValue(value = "pajamuType")
public String getPajamuType() {
    return pajamuType;
}

public void setPajamuType(String pajamuType) {
    this.pajamuType = pajamuType;
}

@FieldRawValue(value = "pajamuSource")
public String getPajamuSource() {
    return pajamuSource;
}

public void setPajamuSource(String pajamuSource) {
    this.pajamuSource = pajamuSource;
}

@FieldRawValue(value = "pajamuData")
public Date getPajamuData() {
    return pajamuData;
}...

通过注解值返回数据的方法:

public class AbstractModel {

public Object get(String fieldName) {
    Class<? extends AbstractModel> obj = this.getClass();

    for (Method method : obj.getDeclaredMethods()) {
        if (method.isAnnotationPresent(FieldRawValue.class)) {
            FieldRawValue annotation = method
                    .getAnnotation(FieldRawValue.class);
            if (annotation.value().equals(fieldName)) {
                try {
                    return method.invoke(obj);
                } catch (IllegalAccessException | IllegalArgumentException
                        | InvocationTargetException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }
    }

    return null;
}

顺便说一句,没有测试get(String fieldName) 方法,但我希望它可以工作。

那么是否可以在变量上设置注释,然后在需要时找到 set 或 get 方法?

【问题讨论】:

    标签: java annotations


    【解决方案1】:

    我不确定为什么要复制字段名并将其放在注释中,但是这里是解决方案(需要 Java8):

    public class AbstractModel {
    
        public Object get(String fieldName) throws InvocationTargetException, IllegalAccessException {
            FieldRawValue fieldRawValueAnnotation = validateExistsAndGetFieldRawValueAnnotation(fieldName);
    
            String fieldRawValueString = fieldRawValueAnnotation.value();
    
            Optional<Method> getterMethodOptional = Stream.of(getClass().getMethods())
                    .filter(method1 -> method1.getName().equalsIgnoreCase("get" + fieldRawValueString))
                    .findFirst();
    
            return getterMethodOptional
                    .orElseThrow(() -> new RuntimeException("No getter found for @FieldRawValue with value: " + fieldRawValueString))
                    .invoke(this);
        }
    
        public Object set(String fieldName, Object value) throws InvocationTargetException, IllegalAccessException {
            FieldRawValue fieldRawValueAnnotation = validateExistsAndGetFieldRawValueAnnotation(fieldName);
    
            String fieldRawValueString = fieldRawValueAnnotation.value();
    
            Optional<Method> getterMethodOptional = Stream.of(getClass().getMethods())
                    .filter(method1 -> method1.getName().equalsIgnoreCase("set" + fieldRawValueString))
                    .findFirst();
    
            return getterMethodOptional
                    .orElseThrow(() -> new RuntimeException("No setter found for @FieldRawValue with value: " + fieldRawValueString))
                    .invoke(this, value);
        }
    
        private FieldRawValue validateExistsAndGetFieldRawValueAnnotation(String fieldName) {
            Class<? extends AbstractModel> obj = this.getClass();
    
            FieldRawValue fieldRawValueAnnotation = null;
            try {
                fieldRawValueAnnotation = obj.getDeclaredField(fieldName).getAnnotation(FieldRawValue.class);
            } catch (NoSuchFieldException e) {
                new RuntimeException("Field not found: " + fieldName);
            }
    
            if(fieldRawValueAnnotation == null){
                throw new RuntimeException("FieldRawValue annotation not found for a field: " + fieldName);
            }
            return fieldRawValueAnnotation;
        }
    

    型号+用法:

    public class TestModel extends AbstractModel{
    
        @FieldRawValue("test2")
        private String test;
    
        public String getTest2() {
            return test;
        }
    
        public void setTest2(String test) {
            this.test = test;
        }
    
        public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
            TestModel testModel = new TestModel();
    
            Object tst = testModel.get("test"); //== null
            testModel.set("test", "newVal"); //sets new value
            testModel.get("test"); //== "newVal
        }
    
    }
    

    【讨论】:

    • 好的,谢谢,我知道不需要注释。
    • 没错,你可以调用 getClass().getDeclaredField(fieldName) 并且如果字段存在尝试为它找到getter/setter
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多