关于jdk1.8容器hashmap中的变量table加了transient修饰后如何序列化。Serializable
2018年03月12日 11:13:24 qq_35516657 阅读数:462
众所周知,transient修饰符的作用是使该变量在序列化的时候不会被储存。
transient Node<K,V>[] table;
但是hashmap中的变量table是储存了容器中所有的元素,在序列化中不被储存,那么反序列化后hashmap对象中岂不是个空容器?
后来通过细想,table里存的只是引用,就算在序列化中储存到硬盘里,反序列化后table变量里的引用已经没有意义了。
至于hashmap是如何在序列化中储存元素呢?原来是它通过重写Serializable接口中的writeObject方法和readObject方法实现的。下面贴出两个方法的源代码。
-
private void writeObject(java.io.ObjectOutputStream s)
-
throws IOException {
-
int buckets = capacity();
-
// Write out the threshold, loadfactor, and any hidden stuff
-
s.defaultWriteObject();
-
s.writeInt(buckets);
-
s.writeInt(size);
-
internalWriteEntries(s);
-
}
-
/**
-
* Reconstitute the {@code HashMap} instance from a stream (i.e.,
-
* deserialize it).
-
*/
-
private void readObject(java.io.ObjectInputStream s)
-
throws IOException, ClassNotFoundException {
-
// Read in the threshold (ignored), loadfactor, and any hidden stuff
-
s.defaultReadObject();
-
reinitialize();
-
if (loadFactor <= 0 || Float.isNaN(loadFactor))
-
throw new InvalidObjectException("Illegal load factor: " +
-
loadFactor);
-
s.readInt(); // Read and ignore number of buckets
-
int mappings = s.readInt(); // Read number of mappings (size)
-
if (mappings < 0)
-
throw new InvalidObjectException("Illegal mappings count: " +
-
mappings);
-
else if (mappings > 0) { // (if zero, use defaults)
-
// Size the table using given load factor only if within
-
// range of 0.25...4.0
-
float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
-
float fc = (float)mappings / lf + 1.0f;
-
int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
-
DEFAULT_INITIAL_CAPACITY :
-
(fc >= MAXIMUM_CAPACITY) ?
-
MAXIMUM_CAPACITY :
-
tableSizeFor((int)fc));
-
float ft = (float)cap * lf;
-
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
-
(int)ft : Integer.MAX_VALUE);
-
// Check Map.Entry[].class since it's the nearest public type to
-
// what we're actually creating.
-
SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, cap);
-
@SuppressWarnings({"rawtypes","unchecked"})
-
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
-
table = tab;
-
// Read the keys and values, and put the mappings in the HashMap
-
for (int i = 0; i < mappings; i++) {
-
@SuppressWarnings("unchecked")
-
K key = (K) s.readObject();
-
@SuppressWarnings("unchecked")
-
V value = (V) s.readObject();
-
putVal(hash(key), key, value, false, false);
-
}
-
}
-
}