java - Java中泛型类型序列化的HashMap之HashMap

标签 java generics serialization hashmap serializable

已修复,根据工程师 Dollery 的回答,解决方案位于底部。

目标是序列化 Network 类的网络字段。抱歉命名。

我有这个,它编译并正确序列化。

public class Network {
    private HashMap<String, HashMap<String, Number>> network;
    ...
    public void load(String networkFile) throws Exception{
        network = (HashMap<String, HashMap<String, Number>>)Utility.deserialize(Utility.load(networkFile));
    }

    public void save(String networkFile) throws Exception{
        Utility.save(networkFile, Utility.serialize(network));
    }
}

class Number implements Serializable {
    ...
}

我将其更改为通用版本,它可以编译,但不再序列化。我需要以某种方式指定 T 和 Number 的 HashMap 是可序列化的。

public class Network<T extends Serializable> {
    private HashMap<T, HashMap<T, Number>> network;
    ...

    public void load(String networkFile) throws Exception{
        network = (HashMap<T, HashMap<T, Number>>)Utility.deserialize(Utility.load(networkFile));
    }

    public void save(String networkFile) throws Exception{
        Utility.save(networkFile, Utility.serialize(network));
    }
}

class Number implements Serializable {
    ...
}

这是序列化的代码

package Bullib;

import java.io.*;
import java.util.*;
import java.util.regex.*;

public class Utility{

    public static Pattern phrasePattern = Pattern.compile("[^;:!.?]+");
    public static Pattern wordPattern = Pattern.compile("['A-Za-z]+");

    public static Object deserialize(byte[] serialized) throws Exception {
        ByteArrayInputStream bi = new ByteArrayInputStream(serialized);
        ObjectInputStream si = new ObjectInputStream(bi);
        return si.readObject();
    }

    public static byte[] serialize(Object target) throws Exception {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream so = new ObjectOutputStream(bo);
        so.writeObject(target);
        so.flush();
        return bo.toByteArray();
    }

    public static byte[] load(String filename)  throws Exception {
        RandomAccessFile file = new RandomAccessFile(new File(filename), "r");
        byte[] b = new byte[(int)file.length()];
        file.read(b);
        file.close();
        return b;
    }

    public static void save(String filename, byte[] value) throws Exception {
        RandomAccessFile file = new RandomAccessFile(new File(filename), "rw");
        file.write(value);
        file.close();
    }

    public static Collection<String> executeRegex(Pattern pattern, String text){
        LinkedList<String> matches = new LinkedList<String>();
        Matcher m = pattern.matcher(text);
        while (m.find()) {
            matches.add(m.group(0));
        }
        return matches;
    }
}

这是我尝试使用 T 序列化为 StringDouble 时收到的错误

Exception in thread "main" java.io.NotSerializableException: Bullib.Network.Netw
ork
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
        at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
        at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at java.util.HashMap.writeObject(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
        at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
        at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at java.util.HashMap.writeObject(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
        at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
        at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at Bullib.Utility.serialize(Utility.java:21)
        at Bullib.Network.Network.save(Network.java:88)
        at Engine.save(Engine.java:63)
        at Engine.main(Engine.java:88)

每个请求,一个示例测试和错误。正如您所看到的,它产生了与上面相同的异常。我更新了测试,表明如果没有向 map 添加任何内容,测试就会通过,否则会失败。

public static void main(String[] args) throws Exception{
    Network<String> stringtest = new Network<String>("","","");
    stringtest.save("testempty");
    stringtest.load("testempty");
    System.out.println("passed empty");
    stringtest.placeAndMove("fill",0.0);
    stringtest.save("testfilled");
    stringtest.load("testfilled");
    System.out.println("passed filled");
}

java: Bullib/Network/Network
passed empty
Exception in thread "main" java.io.NotSerializableException: Bullib.Network.Netw
ork
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
        at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
        at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at java.util.HashMap.writeObject(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
        at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
        at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at java.util.HashMap.writeObject(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
        at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
        at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
        at java.io.ObjectOutputStream.writeObject0(Unknown Source)
        at java.io.ObjectOutputStream.writeObject(Unknown Source)
        at Bullib.Utility.serialize(Utility.java:21)
        at Bullib.Network.Network.save(Network.java:88)
        at Bullib.Network.Network.main(Network.java:108)

解决办法就是改变

public class Network<T extends Serializable> {
    private HashMap<T, HashMap<T, Number>> network;
    ...

    public void load(String networkFile) throws Exception{
        network = (HashMap<T, HashMap<T, Number>>)Utility.deserialize(Utility.load(networkFile));
    }

    public void save(String networkFile) throws Exception{
        Utility.save(networkFile, Utility.serialize(network));
    }
}

class Number implements Serializable {
    ...
}

public class Network<T extends Serializable> implements Serializable {
    private HashMap<T, HashMap<T, Number>> network;
    ...

    public void load(String networkFile) throws Exception{
        network = (HashMap<T, HashMap<T, Number>>)Utility.deserialize(Utility.load(networkFile));
    }

    public void save(String networkFile) throws Exception{
        Utility.save(networkFile, Utility.serialize(network));
    }
}

class Number implements Serializable {
    ...
}

最佳答案

试试这个:

public class Network implements Serializable

关于java - Java中泛型类型序列化的HashMap之HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20713107/

相关文章:

java - 将 IN 子句与 Java 的 JCR-SQL2 结合使用

java - Jsp加载大量数据到内存?

java - 如何使号码无法接通(类似于调用拦截器)?

Java hashmap 即使键和值不为空也给出空值

arrays - 具有多个闭包的通用函数不起作用

c# - 使用泛型声明 NancyModule

c# - 如何在不知道类型的情况下实例化通用列表

c# 流读取和反序列化

android - 如何通过 bundle 发送对象

android - 可在哪里/何时使用 describeContents()?