HashMap Serializability

2020-05-20 07:20发布

HashMap implements the Serializable interface; so it can be serialized. I have looked at the implementation of HashMap and the Entry[] table is marked as transient. Since the Entry[] table is the one that stores the entire contents of the Map and if it cannot be serialized, how is the Map constructed back during de-serialization

3条回答
欢心
2楼-- · 2020-05-20 08:00

HashMap takes care of its own serialization through the use of the writeObject and readObject methods.

查看更多
等我变得足够好
3楼-- · 2020-05-20 08:02

If you look at the source you will see that it does not rely on the default serialization mechanism, but manually writes out all the entries (as an alternating stream of keys and values):

/**
  * Save the state of the <tt>HashMap</tt> instance to a stream (i.e.,
  * serialize it)
  *
  * @serialData The <i>capacity</i> of the HashMap (the length of the
  *             bucket array) is emitted (int), followed by the
  *             <i>size</i> (an int, the number of key-value
  *             mappings), followed by the key (Object) and value (Object)
  *             for each key-value mapping.  The key-value mappings are
  *             emitted in no particular order.
  */
      private void writeObject(java.io.ObjectOutputStream s)
             throws IOException
         {
             Iterator<Map.Entry<K,V>> i =
                 (size > 0) ? entrySet0().iterator() : null;

            // Write out the threshold, loadfactor, and any hidden stuff
            s.defaultWriteObject();

            // Write out number of buckets
            s.writeInt(table.length);

            // Write out size (number of Mappings)
            s.writeInt(size);

            // Write out keys and values (alternating)
            if (i != null) {
                while (i.hasNext()) {
                    Map.Entry<K,V> e = i.next();
                    s.writeObject(e.getKey());
                    s.writeObject(e.getValue());
                }
            }
        }

This is more compact than the array, which can contain many empty entries and link chains and overhead for Map$Entry wrappers.

Note that it still invokes defaultWriteObject for the "easy" fields. In order for that to work, it has to mark everything else as transient.

查看更多
▲ chillily
4楼-- · 2020-05-20 08:11

HashMaps don't serialize their Entry objects during serialization. Take a look at its writeObject method.

The javadocs explain:

The capacity of the HashMap (the length of the bucket array) is emitted (int), followed by the size (an int, the number of key-value mappings), followed by the key (Object) and value (Object) for each key-value mapping. The key-value mappings are emitted in no particular order.

If you look at the readObject method you will see how the Entry table is rebuilt using the size, keys and values.

查看更多
登录 后发表回答