问题
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.
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)
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());
}
});
}
}
If I keep only the first 2 ArrayLists, the serialization process works. The problem is with the TreeMap.
Is the TreeMap class serializable? (In general) Is it because of the anonymous Comparator?
Here is the main class with the serialization
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();
}
}
}
回答1:
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.
Refactor the anonymous comparator to a top-level, or named inner class, that also implements Serializable.
回答2:
Another way to force the Comparator
to be Serializable
is to convert it to lambda with additional bound cast:
TreeMap<Integer, String> sortedMap = new TreeMap<>(
(Comparator<Integer> & Serializable) (o1, o2) -> {
return o1.compareTo(o2);
}
);
Here is the explanation: Java lambda expressions, casting, and Comparators.
回答3:
Add "implements Serializable" to your Comparator and it should solve the problem.
来源:https://stackoverflow.com/questions/20978922/java-unable-to-serialize-a-objects-which-contain-treemaps-with-comparators