如何在使用反射时检查字段是否具有注释

时间:2016-05-30 13:39:22

标签: java reflection

我使用反射,所以我可以检查另一个类中的某些字段是否有注释。

DummyUser类:

package com.reflec.models;

public class DummyUser {

@NotNull
private String firstName;

private String lastName;

@NotNull
private String email;

public DummyUser() {

}

public DummyUser(String firstName, String lastName, String email) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
}

主要课程:

public static void main(String[] args) {
    DummyUser user = new DummyUser();

    List<Field> list = seekFieldsWithAnnotations(user);         
    System.out.println("Size: " + list.size());
}

public static List<Field> seekFieldsWithAnnotations(Object o) {
    Class<?> clss = o.getClass();
    List<Field> fieldsWithAnnotations = new ArrayList<>();

    List<Field> allFields = new ArrayList<>(Arrays.asList(clss.getDeclaredFields()));
    for(final Field field : allFields ) {
        if(field.isAnnotationPresent((Class<? extends Annotation>) clss)) {
            Annotation annotInstance = field.getAnnotation((Class<? extends Annotation>) clss);
            if(annotInstance.annotationType().isAnnotation()) {
                fieldsWithAnnotations.add(field);
            }
        }
    }
    //clss =  clss.getSuperclass();
    return fieldsWithAnnotations;
}

如果我得到seekFieldsWithAnnotations返回的列表大小,则大小始终为0.实际上我希望它为2,因为字段firstNameemail在他们上面有注释。

如果我返回allFields列表并获得其大小,我会返回3,因为DummyUser类中有三个字段。

所以我认为我出错的地方是

for(final Field field : allFields ) {
    // Here I am trying to check if annotations are present
    if(field.isAnnotationPresent((Class<? extends Annotation>) clss)) {
        Annotation annotInstance = field.getAnnotation((Class<? extends Annotation>) clss);
        if(annotInstance.annotationType().isAnnotation()) {
            fieldsWithAnnotations.add(field);
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我设法通过使用此代码来实现这一点。

public static StringBuilder seekFieldsWithAnnotations(Object object) {
    Class<?> c = object.getClass();

    StringBuilder sb = new StringBuilder();

    Field[] fieldsArr = c.getDeclaredFields();
    List<Field> allFields = new ArrayList<>(Arrays.asList(fieldsArr));

    for(Field field : allFields) {
        if(field.getDeclaredAnnotations().length > 0) {
            Annotation[] fieldAnnots = field.getDeclaredAnnotations();

            sb.append("Field Name: " + field.getName() + "\nAnnotations: ");
            for(int i = 0; i < fieldAnnots.length; i++) {
                if(fieldAnnots.length == 1 || fieldAnnots.length - i == 1) {
                    sb.append(fieldAnnots[i].toString() + "\n\n");
                } else {
                    sb.append(fieldAnnots[i].toString() + ", ");
                }
            }
        } else {
            System.out.println("\"" + field.getName() + "\" has no annotations.\n");
        }
    }
    return sb;
}

答案 1 :(得分:0)

您想要致电getDeclaredAnnotations(),以便为每个字段获取所有声明的注释。 javadoc还清楚地表明您以错误的方式使用getAnnotation()。此方法希望您传递注释类;但是你将封闭对象的类传递给它。

答案 2 :(得分:0)

正如@Jägermeister所说,你应该使用getDeclearedAnnotations

您可以按如下方式简化代码:

public static List<Field> seekFieldsWithAnnotations(Object o) {
    List<Field> fieldsWithAnnotations = new ArrayList<>();
    for (final Field field : o.getClass().getDeclaredFields()) {
        Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
        if (declaredAnnotations.length > 0) {
            fieldsWithAnnotations.add(field);
        }
    }
    return fieldsWithAnnotations;
}