拉取所有带注解的字段(包括对象内部的字段在另一个对象中的字段和内部类中的字段)

Pull all fields with annotation (including fields inside an object in another and fields in inner classes)

您好,我正在创建自定义 Excel 解析编组器工具,您可以参考:

我现在需要的是能够找到所有的注释,特别是如何找到嵌套对象或内部 类 的注释,然后调用 setter/getter.

例如:

public class MyOuterClass {
    private InnerClass innerObject;

    public void setInnerObject (InnerClass innerObject) {
        this.innerObject = innerObject;
    }

    public InnerClass getInnerObject() {
        return innerObject;
    }
}

和;

public class InnerClass {

    // I need to get this field and call its setter from the class passed in, so something like:
    // MyOuterClass outClass; outClass.getInnerObject.setFieldIWant("field")
    // OR outClass.getInnerObject.getFieldIWant
    // But have to be able to do at run time, having no knowledge of the class inside
    // This must also work for a nested class

    @ExcelColumn
    private String fieldIWant;

    public void setFieldIWant(String fieldIWant) {
        this.fieldIWant = fieldIWant;
    }

    public String getFieldIWant() {
        return fieldIWant;
    }
}

以下类实现了AnnotatedElement接口:

  • AccessibleObject
  • Class
  • Constructor
  • Field
  • Method
  • Package

在上述 类 的对象实例上,您可以调用:

<object>.isAnnotationPresent(Class<? extends Annotation> annotationClass)

指定要检查的注释的方法。

所以在你的情况下,@ExcelColumn 的方法调用看起来像:

<object>.isAnnotationPresent(ExcelColumn.class)

然后你可以只使用反射来迭代你想要检查的对象的 fields/methods 等,并在每个对象上调用 .isAnnotationPresent 方法来检查它们是否具有所述注释或没有。

所以如果你想对字段(和嵌套字段)做一些魔术,你可以创建一个像这样的方法:

public void doMagicToFields(Object someObject){
    // Get all declared fields.
    Field[] fields = someObject.getClass().getDeclaredFields();
    for(Field field: fields){
        // If the field is annotated by @ExcelColumn
        if(field.isAnnotationPresent(ExcelColumn.class){
            // If the field is a String (add more checks as needed)
            if(String.class.equals(field.getType()){
                // Set the fields value to "myValue" in case of String.
                field.set(someObject, "myValue");
            }
            // Recursive call to check the nested fields of this field object.
            doMagicToFields(
                // We actually get the field object here.
                field.get(someObject)
            );
        }

    }
}

寻找内在的 classes MyOuterClass.class.getClasses() 会让你开始,但只会给你一个层次的可见性。您需要遍历那些内部 classes(例如,SomeInnerClass.class.getClasses())以检查它们是否有内部 class 自己。

获得 classes 列表后,获取所有方法的列表就像 SomeClass.class.getMethods() 一样简单。

for(Class<?> clazz : OuterClass.class.getClasses()) {
        for(Method method : clazz.getMethods()) {
            if(method.getAnnotation(ExcelColumn.class) != null) {
                System.out.println(clazz.getName() + "." + method.getName());
            }
        }
    }