【问题标题】:HashMap not SerializableHashMap 不可序列化
【发布时间】:2015-12-23 17:58:55
【问题描述】:

HashMapSerializable 键/值应该是 Serializable

但这对我不起作用。尝试了其他一些 IO 流。没有工作。

有什么建议吗?

测试代码

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

堆栈跟踪

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

【问题讨论】:

  • 在我的本地试过。它运行没有任何异常。看来你没有导入正确的类文件?你能分享一下吗?我觉得休息很好。
  • 不要写new String("key"),只写"key""key" 之类的文字已经是 String 对象。您无需显式创建该 String 对象的副本。

标签: java hashmap serializable


【解决方案1】:

异常消息准确地告诉您问题所在:您正在尝试序列化类 SimpleSerializationTest 的实例,而该类不可序列化。

为什么?好吧,您已经创建了一个匿名内部类SimpleSerializationTest,它扩展了HashMap,并且您正在尝试序列化该类的一个实例。内部类总是引用其外部类的相关实例,默认情况下,序列化会尝试遍历这些。

我观察到您使用双括号 {{ ... }} 语法,好像您认为它具有某种特殊意义。重要的是要了解它实际上是两个独立的结构。在构造函数调用之后立即出现的外部大括号标记了内部类定义的边界。内部对绑定了一个实例初始化程序块,例如您可以在 any 类主体中使用(尽管它们在匿名内部类以外的上下文中不常见)。通常,您还可以在外部对中包含一个或多个方法实现/覆盖,在初始化程序块之前或之后。

试试这个:

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

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

        // ...
    }

【讨论】:

  • 有道理,但是当我准确运行 OP 的代码时,它可以序列化。这是为什么呢?
  • @sstan 也许你是从静态上下文中做的?
  • @sstan,使用 OP 的代码逐字记录,我可以准确地重现他报告的异常。
  • 使用菱形运算符。
  • @Puce,这是明智的建议。但是,对于这个答案,我保留了 OP 代码中的那些内容,以避免给人留下他们对序列化产生影响的印象。
【解决方案2】:

您的代码的工作版本:

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

【讨论】:

  • 好吧,只要测试类没有不可序列化的实例成员。在大多数情况下,最好避免内部类以及对可序列化的宿主类的任何相关依赖。
猜你喜欢
  • 2011-10-29
  • 2014-02-10
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
  • 1970-01-01
  • 2023-03-04
相关资源
最近更新 更多