Skip to content

dynamicSizeOf 属性详解

ray.zh edited this page Dec 2, 2023 · 6 revisions

在开发过程中,可以定义一些动态的字段解析,如以下定义:

public class Teacher {
   @MagicField(order = 1)
   private int sizeOfStucent;
   // 这里引用当前对象sizeOfStucent 属性
   @MagicField(order = 2, dynamicSizeOf = "sizeOfStucent")
   private List<Student> students;
   
   // string 也支持变长
   @MagicField(order = 3)
   private int sizeOfName;
   // string 长度取 sizeOfName; 需要注意的是这里是字节数, 不是字符数
   // 这里使用#号代表绝对路径搜寻, 因为此对象本来就是根节点, 所以 "sizeOfName" 和 "#sizeOfName" 都搜寻的属性将会是同一个
   @MagicField(order = 4, dynamicSizeOf = "#sizeOfName")
   private String name;
}

在以上结构中, students 的成员数是通过取sizeOfStucent得到的。

此结构需要注意以下几点:

  • dynamicSizeOf 支持绝对路径引用(使用#号打头)和相对路径(直接使用属性)
    • "a" 是指相对于当前对象的 a 属性
    • "a.b" 是指相对于当前对象的 a 属性,所指向对象的 b 属性
    • "#a" 是指从根路径查开始搜寻 a 属性
    • "#a.b" 是指根路径开始搜寻对象的 a 属性所指向对象的 b 属性
  • dynamicSizeOf 序列化时, 引用值为真实序列化个数。
  • 对象序列化字节时,如果 sizeOfStucent>0 && students.size() > 0, 框架会使用 sizeOfStucent 属性值序列化, 多的元素将会被移除
  • dynamicSizeOf 属性 和 size属性 不能并存
  • dynamicSizeOf 可以使用在 list, array, string 这三种数据类型中
  • dynamicSizeOf 引用的字段类型仅能为 byte, short, int, UByte, UShort, UInt, UNumber, 他们字节数参考首页介绍。
  • dynamicSizeOf 不可引用其他类中的字段, 仅能引用当前类字段且字段声明顺序必须位于当前字段前。

实际序列化举例:

  • 如果 sizeOfStucent=0 && students.size() > 1, 框架将不会序列化任何对象
  • 如果 sizeOfStucent=1 && students.size() > 2, 框架将序列化一个对象
  • 如果 sizeOfStucent=3 && students.size() = 1, 框架将序列化一个对象, 另外2个将会将数据区填充为0x00
  • 如果 sizeOfStucent=Integer.MAX && students.size() = 0, 若可用内存不足, 框架将会抛出OOM异常.
Clone this wiki locally