2015-09-25 12 views
6

HashMap với Serializable khóa/giá trị được cho là Serializable.HashMap không thể nối tiếp

Nhưng nó không hoạt động đối với tôi. Đã thử một số luồng IO khác. Không có tác phẩm nào.

Bất kỳ đề xuất nào?

mã kiểm tra

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

Stack trace

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

Thử nó trên local.it tôi chạy mà không có bất kỳ exception.It vẻ như bạn không được nhập khẩu tập tin lớp học thích hợp? Bạn có thể chia sẻ điều đó không? –

+1

Không viết 'chuỗi mới (" khóa ")', chỉ cần viết '" khóa "'. Một chữ như '" key "' đã là một đối tượng 'String'. Bạn không cần phải tạo một bản sao của đối tượng 'String' đó một cách rõ ràng. – Jesper

Trả lời

15

Thông điệp ngoại lệ sẽ cho bạn biết chính xác những gì vấn đề là: bạn đang cố gắng để serialize một thể hiện của lớp SimpleSerializationTest, và rằng lớp không thể tuần tự hóa được.

Tại sao? Vâng, bạn đã tạo ra một lớp bên trong vô danh của SimpleSerializationTest, một mở rộng HashMap và bạn đang cố gắng tuần tự hóa một cá thể của lớp đó. Các lớp bên trong luôn có các tham chiếu đến cá thể có liên quan của lớp ngoài của chúng, và theo mặc định, tuần tự hóa sẽ cố gắng đi qua các lớp đó.

Tôi quan sát rằng bạn sử dụng cú pháp đôi cú pháp {{ ... }} như thể bạn cho rằng nó có ý nghĩa đặc biệt nào đó. Điều quan trọng là phải hiểu rằng nó thực sự là hai cấu trúc riêng biệt. Cặp dấu ngoặc ngoài xuất hiện ngay lập tức sau khi một lời gọi hàm khởi tạo đánh dấu ranh giới của định nghĩa lớp bên trong. Cặp bên trong ràng buộc một khối khởi tạo thể hiện, chẳng hạn như bạn có thể sử dụng trong bất kỳ phần nào của lớp (mặc dù chúng không bình thường trong các ngữ cảnh khác với các lớp bên trong vô danh). Thông thường, bạn cũng sẽ bao gồm một hoặc nhiều phương thức cài đặt/ghi đè bên trong cặp ngoài, trước hoặc sau khối khởi tạo.

Hãy thử điều này thay vì:

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

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

     // ... 
    } 
+0

Làm cho tinh thần, nhưng khi tôi chạy mã OP chính xác, nó serializes alright. Tại sao vậy? – sstan

+1

@sstan Có lẽ bạn đang làm điều đó từ ngữ cảnh tĩnh? – RealSkeptic

+0

@RealSkeptic: Đúng vậy! Cảm ơn bạn đã chỉ ra điều đó. – sstan

0

Một phiên bản làm việc của mã của bạn:

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

Vâng, ok, miễn là lớp thử nghiệm không có thành viên thể hiện không tuần tự. Nó sẽ là tốt hơn trong hầu hết các trường hợp để chỉ tránh các lớp bên trong và bất kỳ sự phụ thuộc liên quan vào lớp máy chủ được serializable. –

Các vấn đề liên quan