2015-09-25 28 views
6

HashMap z kluczem/wartością Serializable ma być Serializable.HashMap nie Serializable

Ale to nie działa dla mnie. Próbowałem innych strumieni IO. Żadne nie działa.

Jakieś sugestie?

kod testowy

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); 
    } 
} 

Ślad stosu

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

Próbowałem go na moim local.it przebiega bez exception.It wydaje się, że nie są odpowiednie importowania plików klas? Czy możesz to udostępnić? Odpoczynek wygląda dla mnie dobrze. –

+1

Nie pisz "nowego ciągu (" klucz ")', wystarczy napisać '" klawisz "'. Dosłowny, taki jak "klucz", jest już obiektem 'String'. Nie musisz jawnie tworzyć kopii tego obiektu 'String'. – Jesper

Odpowiedz

15

Komunikat wyjątku powie Ci dokładnie, na czym polega problem: próbujesz serializacji instancji klasy SimpleSerializationTest i że klasa nie jest możliwa do serializacji.

Dlaczego? Utworzono anonimową klasę wewnętrzną SimpleSerializationTest, która rozszerza HashMap i próbujesz serializować instancję tej klasy. Klasy wewnętrzne zawsze zawierają odniesienia do odpowiedniej instancji ich klasy zewnętrznej i domyślnie serializacja będzie je przechodzić.

Obserwuję, że używasz składni o podwójnej brace {{ ... }}, jakby uważasz, że ma jakieś szczególne znaczenie. Ważne jest, aby zrozumieć, że w rzeczywistości są to dwie oddzielne konstrukcje. Zewnętrzna para nawiasów klamrowych pojawiających się bezpośrednio po wywołaniu konstruktora oznacza granice wewnętrznej definicji klasy. Para wewnętrzna związała blok inicjalizujący instancję, tak jak można go użyć w jednostce klasy (choć są one nietypowe w kontekście innym niż anonimowe klasy wewnętrzne). Zwykle zawiera również jedną lub więcej implementacji metod/nadpisań w zewnętrznej parze, przed lub po bloku inicjalizatora.

Spróbuj to zamiast:

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

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

     // ... 
    } 
+0

To ma sens, ale kiedy dokładnie uruchomię kod OP, serializuje się w porządku. Dlaczego? – sstan

+1

@sstan Być może robisz to z kontekstu statycznego? – RealSkeptic

+0

@RealSkeptic: To wszystko! Dziękuję za wskazanie tego. – sstan

0

Wersja robocza kodzie:

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

Cóż, OK, o ile klasa testowa nie ma członu instancji nie nadającego się do serializacji. W większości przypadków byłoby lepiej, gdybyśmy unikali klasy wewnętrznej i związanego z nią uzależnienia od klasy hosta, która może być przekształcana do postaci szeregowej. –