2015-09-25 1 views
6

HashMap avec Serializable La clé/valeur est supposée être Serializable.HashMap non sérialisable

Mais ça ne marche pas pour moi. J'ai essayé d'autres flux IO. Aucun ne fonctionne.

Une suggestion?

Code d'essai

public class SimpleSerializationTest { 
    @Test 
    public void testHashMap() throws Exception { 
     HashMap<String, String> hmap = new HashMap<String, String>() {{ 
      put(new String("key"), new String("value")); 
     }}; 

     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     ObjectOutput out = null; 
     out = new ObjectOutputStream(bos); 
     out.writeObject(hmap); 
     byte[] yourBytes = bos.toByteArray(); 
     if (out != null) { 
      out.close(); 
     } 
     bos.close(); 

     ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes); 
     ObjectInput in = null; 
     in = new ObjectInputStream(bis); 
     Object o = in.readObject(); 
     bis.close(); 
     if (in != null) { 
      in.close(); 
     } 

     assertEquals(hmap, o); 
    } 
} 

trace de la pile

java.io.NotSerializableException: SimpleSerializationTest 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 
    at SimpleSerializationTest.testHashMap(SimpleSerializationTest.java:18) 

Process finished with exit code 0 
+0

Essayé sur mon local.it fonctionne sans exception.It vous semble n'êtes pas d'importer des fichiers de classe appropriés? Pouvez-vous partager cela? Le reste me va bien. –

+1

N'écrivez pas 'new String (" key ")', écrivez simplement "key" '. Un littéral tel que «key» est déjà un objet «String». Vous n'avez pas besoin de créer explicitement une copie de cet objet 'String'. – Jesper

Répondre

15

Le message d'exception vous dit exactement ce que le problème est: vous essayez de sérialiser une instance de classe SimpleSerializationTest, et que La classe n'est pas sérialisable.

Pourquoi? Eh bien, vous avez créé une classe interne anonyme de SimpleSerializationTest, une qui s'étend HashMap, et vous essayez de sérialiser une instance de cette classe. Les classes internes ont toujours des références à l'instance pertinente de leur classe externe et, par défaut, la sérialisation essaie de les traverser.

Je remarque que vous utilisez une syntaxe double-accolade {{ ... }} comme si vous pensez qu'elle a une sorte de signification particulière. Il est important de comprendre qu'il s'agit en fait de deux constructions distinctes. La paire externe d'accolades apparaissant immédiatement après l'invocation d'un constructeur marque les limites de la définition de classe interne. La paire interne a lié un bloc d'initialisation d'instance, tel que vous pouvez utiliser dans n'importe quel corps de classe (bien qu'ils soient inhabituels dans les contextes autres que les classes internes anonymes). Habituellement, vous incluez également une ou plusieurs implémentations/substitutions de méthodes dans la paire externe, avant ou après le bloc d'initialisation.

Essayez ceci:

public void testHashMap() throws Exception { 
     HashMap<String, String> hmap = new HashMap<String, String>(); 

     hmap.put(new String("key"), new String("value")); 

     // ... 
    } 
+0

Ca a du sens, mais quand je cours exactement le code OP, il se sérialise bien. Pourquoi donc? – sstan

+1

@sstan Peut-être que vous le faites dans un contexte statique? – RealSkeptic

+0

@RealSkeptic: C'est tout! Merci d'avoir fait remarquer cela. – sstan

0

Une version de travail de votre code:

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.ObjectInput; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutput; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
import java.util.HashMap; 

import org.junit.Test; 

import junit.framework.Assert; 

public class SimpleSerializationTest implements Serializable{ 
    @Test 
public void testHashMap() throws Exception { 
    HashMap<String, String> hmap = new HashMap<String, String>() {{ 
     put(new String("key"), new String("value")); 
    }}; 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ObjectOutput out = null; 
    out = new ObjectOutputStream(bos); 
    out.writeObject(hmap); 
    byte[] yourBytes = bos.toByteArray(); 
    if (out != null) { 
     out.close(); 
    } 
    bos.close(); 

    ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes); 
    ObjectInput in = null; 
     in = new ObjectInputStream(bis); 
     HashMap<String, String> o = (HashMap<String, String>) in.readObject(); 
     bis.close(); 
     if (in != null) { 
      in.close(); 
     } 

     Assert.assertEquals(hmap, o); 
    } 
} 
+1

Eh bien, d'accord, tant que la classe de test n'a pas de membre d'instance non sérialisable. Il serait préférable, dans la plupart des cas, d'éviter la classe interne et toute dépendance associée à la classe hôte étant sérialisable. –