...
Consequently, the hashcode of an object need not remain consistent across different executions of the application. Similarly, if an object is serialized, its hashcode may not stay consistent with the original value. This introduces several hurdles; for example, upon deserialization it is impossible to retrieve the object because its corresponding key value could have changed.
Noncompliant Code Example
Wiki Markup |
---|
This noncompliant code example uses the {{Key}} class as the key index for the hashtable{{Hashtable}}. According to the Java API \[[API 06|AA. Java References#API 06]\] class {{Hashtable}} documentation: |
...
This example follows the above advice but serialization is still at the mercy of the implementation of the hashcode
method. It is not required to produce a key value (hashcode) that is consistent across different executions of the program or during (de)serialization. Consequently, using the default serialized form of the hashtable may be inappropriate. In this noncompliant code example, it is not possible to retrieve the value of the object using the original key after deserialization.
Code Block | ||
---|---|---|
| ||
class Key implements Serializable { //overrides Overrides hashcode and equals methods } class HashSer { public static void main(String[] args) throws IOException, ClassNotFoundException { Hashtable<Key,String> ht = new Hashtable<Key, String>(); Key key = new Key(); ht.put(key, "Value"); System.out.println("Entry: " + ht.get(key)); // retrieveRetrieve using the key, works // Serialize the Hashtable object FileOutputStream fos = new FileOutputStream("hashdata.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(ht); oos.close(); // Deserialize the Hashtable object FileInputStream fis = new FileInputStream("hashdata.ser"); ObjectInputStream ois = new ObjectInputStream(fis); Hashtable<Key, String> ht_in = (Hashtable<Key, String>)(ois.readObject()); ois.close(); if(ht_in.contains("Value")) // checkCheck if the object actually exists in the Hashtable System.out.println("Value was found in deserialized object."); if (ht_in.get(key) == null) // getsGets printed System.out.println("Object was not found when retrieved using the key."); } } |
...
Code Block | ||
---|---|---|
| ||
class HashSer { public static void main(String[] args) throws IOException, ClassNotFoundException { Hashtable<Integer,String> ht = new Hashtable<Integer, String>(); ht.put(new Integer(1), "Value"); System.out.println("Entry: " + ht.get(1)); // retrieveRetrieve using the key // Serialize the Hashtable object FileOutputStream fos = new FileOutputStream("hashdata.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(ht); oos.close(); // Deserialize the Hashtable object FileInputStream fis = new FileInputStream("hashdata.ser"); ObjectInputStream ois = new ObjectInputStream(fis); Hashtable<Integer, String> ht_in = (Hashtable<Integer, String>)(ois.readObject()); ois.close(); if(ht_in.contains("Value")) // checkCheck if the object actually exists in the Hashtable System.out.println("Value was found in deserialized object."); if (ht_in.get(1) == null) // doesDoes not get printed System.out.println("Object was not found when retrieved using the key."); } } |
This problem can also be avoided by overriding the equals()
and the hashcode()
method in the Key
class, though it is best to avoid employing hash tables that are known to use implementation defined parameters.
...