我了解到,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关键字的一项练习。
答案 0 :(得分:2)
如何决定不通过提供瞬态来序列化成员 改性剂?
例如,为什么成员字段表不是序列化的一部分?
因为(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);
}
}
}
}