天天看点

集合 - 标记接口(Marker Interface)

集合中某些类或者接口继承或者实现了标记接口(Marker Interface),这里大概说下几个常用的标记接口的用处与底层实现。

标记接口

在集合类中涉及到下列几个标记接口(Marker Interface)

Cloneable

标记该类可以浅拷贝

  1. 浅拷贝只拷贝对象参数的基本类型部分,如果要拷贝引用类型,达到深拷贝的目的,需要覆写 Object.clone() 方法。

Serializable

标记该类产生的对象可序列化

  1. 可以通过

    ObjectInputStream

    ObjectOutputStream

    来获取或者写入

    Java

    独有的序列化方式序列化过的对象;
  2. 其中

    serialVersionUID

    为兼容模型而设计(这里的设计不存在安全性考虑,因为明文传输),如果没有设定,

    JVM

    会根据当前序列化的类的结构计算校验和,得到一个固定的

    Long

    值,但当类结构改变时

    UID

    也会随之改变,所以为了防止序列化失败,除非不想兼容之前模型,这里建议还是设定一个

    serialVersionUID

  3. 获取类定义时,还通过

    ConcurrentHashMap<WeakClassKey, SoftReference>

    来保存 序列化对象的

    Class

    (继承自

    WeakReference

    )和 即将序列化的对象定义实体(在

    SoftReference

    中保存

    ObjectStreamClass

    EntryFuture

    等),用来辅助暂存序列化类的定义;
  4. ArrayList

    HashMap

    等存在部分数组索引的值为空的情况,为了序列化/反序列化过程中不产生空元素,

    Serialzable

    提供了

    writeObject

    readObject

    等私有方法来定制序列化方式;
  5. 对象参数存在

    transient

    但想序列化的情况,同样可以通过

    4

    的方法实现;
  6. writeObject

    readObject

    等方法参数序列化、反序列化时存在顺序性(类似

    Protobuf

    IDL

    有索引),这点需要注意。

RandomAccess

标记为支持快速随机访问的类

  1. 标记该类数据模型底层使用数组,查询时间复杂度为

    O(n)

    ,推荐遍历优先使用索引而不是迭代器。

Externalizable

标记为自定义序列化方式

  1. 有两个待实现接口

    writeExternal

    readExternal

  2. Externalizable

    接口优先级高于

    Serializable

    ,如果实现该接口,

    Serializable

    的隐式定义方法,如:

    writeObject

    readObject

    等都不会生效。