• 通过添加注解实现按顺序输出类属性


    开发过程中为了方便解析JSON数组数据,所以客户端类属性按照JSON数组数据顺序进行编写,然后通过反射分别给每个属性复制:

    反射获取属性

    新建一个实体类

    public class InfoBean {
        public String name;
        public String url;
        public int page;
        public boolean isTest;
        public AddressDTO address;
        public List links;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    通过Java的反射机制来获取类的字段列表

    var obj = InfoBean()
    var fields = obj.javaClass.declaredFields
    for (field in fields){
           Log.i(TAG,"field ${field.name}")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    打印日志

    I/MainActivity: field address
    I/MainActivity: field isTest
    I/MainActivity: field links
    I/MainActivity: field name
    I/MainActivity: field page
    I/MainActivity: field url
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    很失望,打印的属性顺序和代码属性的顺序并不一致,因为getDeclaredFields() 方法返回的字段数组并不保证按照代码顺序排序。字段的顺序可能受到多种因素的影响,例如编译器、JVM 实现以及其他因素。
    根据 Java 文档,getDeclaredFields() 方法返回的字段数组是以任意顺序返回的,没有特定的排序保证。如果需要按照特定顺序获取字段,可以使用其他方法来实现,比如通过字段名称排序或者自定义排序规则。

    添加注解

    我们使用自定义注解来为字段添加排序信息,并根据注解值进行排序。然而,需要注意的是,注解本身并不能直接影响字段的排序顺序,而是需要在代码中编写逻辑来实现按照注解值排序的功能。

    1. 自定义注解 FieldOrder

      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.FIELD)
      public @interface FieldOrder {
          int value();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

      在 FieldOrder.java 文件中,使用 @interface 关键字来定义注解,并为注解添加所需的元素。在这种情况下,我们需要为注解添加一个整数类型的 value 元素,用于表示字段的排序值。

    2. 使用自定义注解

       public class InfoBean {
           @FieldOrder(1)
           public String name;
           @FieldOrder(2)
           public String url;
           @FieldOrder(3)
           public int page;
           @FieldOrder(4)
           public boolean isTest;
           @FieldOrder(5)
           public AddressDTO address;
           @FieldOrder(6)
           public List links;
       }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    3. 排序逻辑来实现字段排序

       var obj = InfoBean()
       var fields = obj.javaClass.declaredFields
       fields.sortWith(compareBy { field -> field.getAnnotation(FieldOrder::class.java).value })
       for (field in fields){
           Log.i(TAG,"field ${field.name}")
       }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    打印日志

    I/MainActivity: field name
    I/MainActivity: field url
    I/MainActivity: field page
    I/MainActivity: field isTest
    I/MainActivity: field address
    I/MainActivity: field links
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    完美

    @Retention(RetentionPolicy.RUNTIME) 是一个用于指定注解的保留策略的元注解(meta-annotation)。它用于告诉编译器和运行时环境在何时可以访问注解。

    @Retention 元注解有三个预定义的保留策略,分别是:

    • RetentionPolicy.SOURCE:注解仅在源代码中保留,编译后的字节码中不包含注解信息,因此无法在运行时获取。
    • RetentionPolicy.CLASS:注解在编译后的字节码文件中保留,但在运行时无法获取。这是默认的保留策略。
    • RetentionPolicy.RUNTIME:注解在编译后的字节码文件中保留,并可以在运行时通过反射机制获取和使用注解信息。
      @Target(ElementType.FIELD) 是另一个元注解,用于指定注解可以应用的目标元素类型。在这个例子中,@Target(ElementType.FIELD) 表示该注解可以应用在字段上。

    综合起来,@Retention(RetentionPolicy.RUNTIME) 和 @Target(ElementType.FIELD) 的组合表示该注解在运行时保留,并且可以应用在字段上。这意味着我们可以在运行时通过反射获取字段上的注解信息,并根据注解值进行相应的操作,比如排序。

  • 相关阅读:
    华为手机的钱包里没有门钥匙要怎样弄
    备忘录模式
    力扣 2. 两数相加
    【React】【react-globe.gl】3D Objects效果
    并发编程模型的两个关键问题
    【Java基础】数组动态、静态初始化、元素访问及内存分配
    elementui 列表页进入详情再返回分页被重置
    mysql基本操作增删改查
    基于Maven的Spring开发环境搭建
    OpenAI超级对齐负责人:“驾驭”超级智能的四年计划
  • 原文地址:https://blog.csdn.net/wolf0706/article/details/134020321