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

news/2024/5/19 3:02:51 标签: 1024程序员节, 反射, 注解

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

反射获取属性

新建一个实体类

public class InfoBean {
    public String name;
    public String url;
    public int page;
    public boolean isTest;
    public AddressDTO address;
    public List<LinksDTO> links;
}

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

var obj = InfoBean()
var fields = obj.javaClass.declaredFields
for (field in fields){
       Log.i(TAG,"field ${field.name}")
}

打印日志

I/MainActivity: field address
I/MainActivity: field isTest
I/MainActivity: field links
I/MainActivity: field name
I/MainActivity: field page
I/MainActivity: field url

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

添加注解

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

  1. 自定义注解 FieldOrder

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface FieldOrder {
        int value();
    }
    

    在 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<LinksDTO> links;
     }
    
  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}")
     }
    

打印日志

I/MainActivity: field name
I/MainActivity: field url
I/MainActivity: field page
I/MainActivity: field isTest
I/MainActivity: field address
I/MainActivity: field links

完美

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

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

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

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


http://www.niftyadmin.cn/n/5118265.html

相关文章

k8s-----7、Pod健康检查

健康检查 1、健康检查 1、健康检查 健康检查可以分为两种 1、livenessProbe (存活检查)。如果检查失败&#xff0c;将杀死容器&#xff0c;通过Pod的restartPolicy来操作。 2、readinessProbe(就绪检查)。如果检查失败&#xff0c;k8s会将Pod从Service endpoints中剔除。 Pr…

Spring高手之路15——掌握Spring事件监听器的内部逻辑与实现

文章目录 1. 事件的层次传播2. PayloadApplicationEvent的使用3. 为什么选择自定义事件&#xff1f;4. 事件广播原理4.1 Spring 5.x的事件模型概述4.2 发布事件publishEvent源码分析4.3 Spring事件广播&#xff1a;从ApplicationEventMulticaster开始4.4 Spring事件发布与处理流…

这是什么牛马机器视觉公司

这是什么牛马机器视觉公司&#xff0c;签订培训协议服务期&#xff0c;培训完三年内跑路直接赔两万。 我看到很多外包公司签订此类合同&#xff0c;当然也有培训机构也会玩此种协议。 对于我这种职场老手&#xff0c;我应该给大家分析下&#xff1a; 我们先看下什么是服务期…

C++基础语法——C++11

目录 1. 统一的列表初始化 ①{}进行初始化 ②std::initializer_list 1.类型 2.使用场景 2.声明 ①auto ②decltype ③nullptr 3.范围for 4.右值引用与移动语义 ①左值引用与右值引用 ②左值引用与右值引用的比较 ③左值引用与右值引用的使用场景与意义、移动语义…

C语言基础例题7例-结构体篇

文章目录 1-5题前言题目例题6&#xff08;难度★ ☆ ☆ ☆ ☆&#xff09;例题7&#xff08;难度★ ★ ☆ ☆ ☆&#xff09; 答案例题1解析 例题2解析 1-5题 C语言基础例题1-3题-指针篇 C语言基础例题4-5题-二维数组篇 前言 本篇文章的题目为C的基础练习题&#xff0c;结构…

【原创】解决Kotlin无法使用@Slf4j注解的问题

前言 主要还是辟谣之前的网上的用法&#xff0c;当然也会给出最终的使用方法。这可是Kotlin&#xff0c;关Slf4j何事&#xff01;&#xff1f; 辟谣内容&#xff1a;创建注解来解决这个问题 例如&#xff1a; Target(AnnotationTarget.CLASS) Retention(AnnotationRetentio…

第九章:最新版零基础学习 PYTHON 教程—Python 元组(第四节 -Python连接元组的方法)

很多时候,在处理记录时,我们可能会遇到需要添加两条记录并将它们存储在一起的问题。这需要串联。由于元组是不可变的,因此这个任务变得不太复杂。让我们讨论执行此任务的某些方法。 目录