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

Java 拉取带有注释的所有字段(包括另一个对象中对象内部的字段和内部类中的字段),java,reflection,annotations,Java,Reflection,Annotations,您好,我正在创建一个自定义Excel解析封送拆收器工具,您可以参考以下内容: 我现在需要的是能够找到所有注释,特别是如何找到嵌套对象或内部类的注释,然后调用setter/getter 例如: public class MyOuterClass { private InnerClass innerObject; public void setInnerObject (InnerClass innerObject) { this.innerObject = inn

您好,我正在创建一个自定义Excel解析封送拆收器工具,您可以参考以下内容:

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

例如:

public class MyOuterClass {
    private InnerClass innerObject;

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

    public InnerClass getInnerObject() {
        return innerObject;
    }
}


以下类实现了
AnnotatedElement
接口:

  • AccessibleObject
  • Class
  • Constructor
  • 字段
  • 方法
  • Package
在所述类的对象实例上,您可以调用:

<object>.isAnnotationPresent(Class<? extends Annotation> annotationClass)
然后,您可以使用反射来迭代要检查的对象的字段/方法等,并对每个字段/方法调用
。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)
            );
        }

    }
}

查找内部类
MyOuterClass.class.getClasses()
将帮助您开始,但只提供一个级别的可见性。您需要遍历这些内部类(例如,
SomeInnerClass.class.getClass()
),以检查它们本身是否有内部类

一旦有了类列表,就可以像
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());
            }
        }
    }
for(类clazz:OuterClass.Class.getClasses()){
for(方法:clazz.getMethods()){
if(method.getAnnotation(ExcelColumn.class)!=null){
System.out.println(clazz.getName()+““+method.getName());
}
}
}

可能重复感谢,我想这是我需要做的,但是为了调用setter或getter,我还必须动态地为PropertyUtils.getNestedProperty(Object,string)PropertyUtils.setNestedProperty(Object,string,Object)构建字符串。啊,是的,这有点棘手,最好留给外部包装。我不确定你被困在这里的是什么部分。谢谢,是的,我基本上创建了一个递归方法来提取我想要的所有字段,谢谢你的帮助。这对我刚才帮助很大,但我有一个更正:要检查字段是否是字符串,你需要的是String.class.equals(field.getType())而不是String.class.equals(field.getClass())。getClass方法返回字段实例的类,即它总是java.lang.reflect.Field。
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)
            );
        }

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