为什么会员领域'表'在' java.util.HashMap'是暂时的?

时间:2015-09-07 06:32:14

标签: java serialization deserialization

我了解到,transient关键字阻止了使用transient关键字声明的实例字段的在序列化对象时保持不变。

以下是java.util.HashMap的代码:

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {

             ....
             static class Node<K,V> implements Map.Entry<K,V> {...}
             transient Node<K,V>[] table;
}

为什么实例字段table的值不是序列化的一部分?因为table字段的值是实现角度class HashMap实例的实际内容。

注意:here是关于使用transient关键字的一项练习。

3 个答案:

答案 0 :(得分:2)

  

如何决定不通过提供瞬态来序列化成员   改性剂?

  1. 当字段引用无序序列化的资源时。例如,OutputStream或Window句柄。
  2. 当可以从序列化的其他信息重建字段时。这有助于减少需要写入的数据量。
  3.   

    例如,为什么成员字段表不是序列化的一部分?

    因为(2)。查看readObject类中的HashMap方法。使用班级中的其他信息重建table字段。

答案 1 :(得分:0)

HashMap的一个实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的桶数,初始容量只是创建哈希表时的容量。

由于你提到的例子中的'table'是用其他2个参数构造的,并且由这个数据结构用于表示,所以不需要为它的序列化而烦恼。

E.g。你可以在下面看到它:

   public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);

        // Find a power of 2 >= initialCapacity
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;

        this.loadFactor = loadFactor;
        threshold = (int)(capacity * loadFactor);
        table = new Entry[capacity];
        init();
    }

答案 2 :(得分:0)

由于Node<K, V>[] table是稀疏的,因此序列化所有此数组是浪费时间。相反,我们只需要序列化数组中的非空元素即可,足以在以后重建表。

    void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
        Node<K,V>[] tab;
        if (size > 0 && (tab = table) != null) {
            for (int i = 0; i < tab.length; ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next) {
                    s.writeObject(e.key);
                    s.writeObject(e.value);
                }
            }
        }
    }