当前位置:首页|资讯|ChatGPT|GitHub

从零开始的Minecraft - nbt序列化库开发:注解Ignore和InstanceAs

作者:疑似叉叉星来的鹩八哥发布时间:2023-03-09

项目开篇:项目介绍 & 当前开发成果总结

上一篇:从零开始的Minecraft - Nbt 序列化库开发:添加功能:LocateAt注解

项目地址:https://github.com/Cmyna/mnbt(可使用Jitpack配合Gradle/Maven导入项目)

摘要:简单解释了下两个功能性注解InstanceAs和Ignore

前置知识:java,kotlin和其注解相关知识,对本项目其余内容的了解

特别感谢:ChatGPT的文案

这两个注解主要补充了两个迫切需要的功能:当一个类的字段被声明为一个接口时该如何处理,以及当我们不希望一个字段不被Mnbt序列化/反序列化时该如何处理。

InstanceAs注解(字面意思为”实例化为“)

注解负责处理字段对象,可以让Mnbt不以字段声明的类型来处理,而是以注解声明的类型进行处理,例如:

如果不使用InstanceAs注解,那么Mnbt在处理该字段时只能知道这个字段是一个接口/抽象类,那么Mnbt便无法从创建一个该接口字段的实例,那么也就无法从Tag对象转换成该字段需要的值。使用InstanceAs注解后就能通过字段注解获取字段的实现类型,从而正常处理该字段。

实现该注解的功能也很简单,负责处理反射转换对象的ReflectiveConverter只需要判断传入的MTypeToken类型中的字段声明是否带有该注解,并根据注解声明的类型处理字段转换,而不是字段本身的类型声明处理即可。唯一需要注意的只有下面2个问题:

  • 注解声明的类型必须是字段声明类型的子类

  • 注解声明的类型不可为接口/抽象类

为处理这两个问题,实际代码实现如下:

Ignore注解:

用于指定是否忽略某个字段的 Ignore 注解。Ignore 注解可以指定在将对象转换为 Tag 对象或将 Tag对象 转换为其他java对象时忽略特定的字段。该注解包括 ignoreToTag 和 ignoreFromTag 两个布尔值参数,用于指定是否忽略序列化或反序列化。代码实现如下:

其中fieldValueProvider是一个实现了FieldValueProvider的类,参数用于指定在从Tag对象转成java对象过程中,需要提供给该字段的值的来源。当一个字段被标记为 @IgnoreFromTag 时,该注解可以指定一个实现了 FieldValueProvider 接口的类,用于提供需要反序列化的字段的值。该接口只有一个方法 provide,用于返回指定字段的值。因此,fieldValueProvider 参数指定的类需要实现该接口并提供相应的逻辑,以便在反序列化时正确地提供需要的字段值。需要注意的是,由于提供的是一个KClass(或javaClass)声明,实际上该类的实例是由mnbt自行创建,而且要求该类必须提供一个空构造器。FieldValueProvider的声明如下:

因为每次使用Ingore注解都需要显式指定其三个参数,为了简化注解使用,又实现了两个注解:IgnoreFromTag和IgnoreToTag(也和参数同名)。如注解名字所示,IgnoreFromTag用于指定在从Tag对象转成java对象时是否忽略该字段,因此需要FieldValueProvider实现类的参数,而IgnoreToTag则不需要任何参数,其所本身的含义就已经代表了Ignore.ignoreToTag = true。

由于Ignore注解本身并不复杂,所以其在mnbt的实现也很简单,也是在ReflectiveConverter中实现相应功能,唯一需要注意的是其两个子注解IgnoreFromTag和IgnoreToTag也要能发挥相应的功能。我的做法是在得到Ignore注解后尝试将其转成IgnoreFromTag/IgnoreToTag注解对象,如果为空,那么说明Ignore注解对应的参数为false。


Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1