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

开发过程中为了方便解析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) 的组合表示该注解在运行时保留,并且可以应用在字段上。这意味着我们可以在运行时通过反射获取字段上的注解信息,并根据注解值进行相应的操作,比如排序。

  • 16
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值