使用注释拉出所有字段(包括另一个对象内的字段和内部类中的字段)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用注释拉出所有字段(包括另一个对象内的字段和内部类中的字段)相关的知识,希望对你有一定的参考价值。

您好我正在创建一个自定义Excel解析marshaller工具,您可以参考:How can I call getter/setter for property marked with custom annotation?

我现在需要的是能够找到所有注释,特别是如何找到嵌套对象或内部类的注释,然后调用该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)

然后你可以使用反射来迭代你想要检查的对象的字段/方法等,并在每个对象上调用.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.getClass()){
                // 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.getClasses())以检查它们是否自己有内部类。

一旦你有了类列表,它就像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());
            }
        }
    }

以上是关于使用注释拉出所有字段(包括另一个对象内的字段和内部类中的字段)的主要内容,如果未能解决你的问题,请参考以下文章

Oracle数据库中查看所有表和字段以及表注释.字段注释

SwiftUI,使用按钮将文本字段内的值相乘

如何根据其中引用的当前帖子拉出帖子对象?

Django QuerySets - 如何注释一个字段但返回另一个字段?

注释另一个模型中的字段值出现次数

姜戈初学者。如何更新所有对象并将某个字段设置为另一个字段的函数值?