浅析transient关键字

本文讲述的是Java中transient关键字的作用

前言

在阅读ArrayList和Vector源码的学习过程中,我发现存储ArrayList的元素的数组缓冲区用到了transient关键字来进行存储优化,而Vector却没有,这是为什么呢?


一、transient

transient关键字是开发中用的比较少的一个关键字,它在序列化和反序列化中比较重要,通常面试时会考察它的作用和它的使用场景,还有它在什么情况下会失效。transient的作用是用来防止属性被序列化

二、ArrayList中transient的作用

ArrayList

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access

ArrayList中writeObject的实现

    /**
     * Save the state of the <tt>ArrayList</tt> instance to a stream (that
     * 将 ArrayList 实例的状态保存到流中(即序列化它)。
     * is, serialize it).
     *
     * @serialData The length of the array backing the <tt>ArrayList</tt>
     *             instance is emitted (int), followed by all of its elements
     *             (each an <tt>Object</tt>) in the proper order.
     */
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

这里ArrayList实现了writeObject方法,可以看到只会保存List的实际size个数的elementData,也就是说保存非空数组位置上的数据,并且提供了fast-fail快速失败机制,可以提供弱一致性。

Vector

    /**
     * The array buffer into which the components of the vector are
     * stored. The capacity of the vector is the length of this array buffer,
     * and is at least large enough to contain all the vector's elements.
     *
     * <p>Any array elements following the last element in the Vector are null.
     *
     * @serial
     */
    protected Object[] elementData;

Vectort中writeObject的实现

    /**
     * Save the state of the {@code Vector} instance to a stream (that
     * is, serialize it).
     * This method performs synchronization to ensure the consistency
     * of the serialized data.
     */
    private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
        final java.io.ObjectOutputStream.PutField fields = s.putFields();
        final Object[] data;
        synchronized (this) {
            fields.put("capacityIncrement", capacityIncrement);
            fields.put("elementCount", elementCount);
            data = elementData.clone();
        }
        fields.put("elementData", data);
        s.writeFields();
    }

Vector 也实现了 writeObject 方法,但方法并没有像 ArrayList 一样进行优化存储
data = elementData.clone();
clone()的时候会把 null 值也拷贝。所以保存相同内容的 Vector 与 ArrayList, Vector 的占用的字节比 ArrayList 要多


三、区别

  • ArrayList 是非同步实现的一个单线程下较为高效的数据结构(相比 Vector 来说)。 ArrayList 只通过一个修改记录字段提供弱一致性,主要用在迭代器里。没有同步方法。 即上面提到的 Fast-fail 机制.ArrayList 的存储结构定义为 transient,重写 writeObject 来实现自定义的序列化,优化了存储。
  • 同步处理:Vector 同步,ArrayList 非同步 Vector 缺省情况下增长原来一倍的数组 长度,ArrayList 是 0.5 倍. ArrayList: int newCapacity = oldCapacity + (oldCapacity >> 1); ArrayList 自动扩大容量为原来的 1.5 倍(实现的时候,方法会传入一个期望的最小容量,若扩容后容量仍然小于最小容量,那么容量就为传入的最小容量。扩 容的时候使用的 Arrays.copyOf 方法最终调用 native 方法进行新数组创建和数据拷贝)。
  • Vector: int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
  • Vector 指定了initialCapacity,capacityIncrement 来初始化的时候,每次增长 capacityIncrement
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原来是曹孟德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值