Java无法使用比较器序列化包含TreeMap的对象 [英] Java unable to serialize a objects which contain TreeMaps with Comparators

查看:92
本文介绍了Java无法使用比较器序列化包含TreeMap的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个任务(针对Uni大学的OOP课程)是一个相当大的项目:一个学校注册簿,学生可以看到自己的成绩,老师可以添加成绩等等.

I have as an assignment (for the OOP course from Uni) a pretty large project: a school register, where students can see their grades, teachers can add grades and so on.

基础"类是一个单例,其中包含所有使用的类(Java),例如一系列用户,类(如在学校中的类)以及将类和教师与课程相关联的TreeMap.

The "base" class is a singleton which contains all the classes (Java) used, such as an array of users, classes (as in school classes) and a TreeMap that associates classess and teachers to courses.

我想序列化此基类(中央),以保存修改后的数据.问题是我得到了这个异常

I want to serialize this base class (Central), in order to save the modified data. The problem is that I get this exception

java.io.NotSerializableException: liceu.Central$1
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:440)
at java.util.TreeMap.writeObject(TreeMap.java:2265)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at liceu.Main.main(Main.java:31)

我所有的类都实现了Serializable,并且它们没有瞬态或静态字段(单例除外,该类具有实例变量和getInstance方法为静态变量).

All of my classes implement Serializable, and they don't have transient or static fields (except for the singleton, which has the instance variable and getInstance method as statics).

因为要发布大量的代码(在提交之前我会冒险通过发布它来使我的作业无效),所以我试图通过隔离错误来进行概念证明.

Because it would be quite a lot of code to post (and I would risk to nullify my assignment by publishing it before submitting) I have tried to make a proof of concept by trying to isolate the error.

public class Central implements Serializable
{
    private ArrayList <User> users;
    private ArrayList <Class> classess;
    private TreeMap <Course, TreeMap <Class, Professor>> reunite;
    private static Central instance = null;

    private Central()
    {
        users = new ArrayList<>();
        classess = new ArrayList<>();
        reunite = new TreeMap<>(new Comparator<Student>(){
            @Override
            public int compare(Student e1, Student e2)
            {
                return e1.getName().compareTo(e2.getName());
            }
        });
    }
}

如果仅保留前两个ArrayList,则序列化过程将正常进行.问题出在TreeMap上.

If I keep only the first 2 ArrayLists, the serialization process works. The problem is with the TreeMap.

TreeMap类可序列化吗?(一般来说)是因为匿名比较器吗?

Is the TreeMap class serializable? (In general) Is it because of the anonymous Comparator?

这里是序列化的主要类

public class Main
{
    public static void main(String args[])
    {
        Central cent = Central.getInstance();
        FileOutputStream fos;
        ObjectOutputStream oos;

        cent.addUser(new Student(3,"id","pass","name","surname"));
        cent.addUser(new Student(3,"id2","pass","name","surname"));
        cent.addUser(new Student(3,"id1","pass","name","surname"));
        try
        {
            fos = new FileOutputStream("save.txt");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(cent);
        }

        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

推荐答案

TreeMap包含对用于比较键的比较器的引用.比较器是不可序列化的匿名类的实例.因此,您会收到此异常.

The TreeMap holds a reference to the comparator it uses to compare the keys. And the comparator is an instance of an anonymous class that is not serializable. So you get this exception.

将匿名比较器重构为顶级类或命名内部类,该类也实现了Serializable.

Refactor the anonymous comparator to a top-level, or named inner class, that also implements Serializable.

这篇关于Java无法使用比较器序列化包含TreeMap的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆