java.io.NotSerializableException:java.util.HashMap $ Node

时间:2015-01-04 18:51:28

标签: java notserializableexception

我编写了一个与Object Serialization结合使用的类。在序列化阶段,似乎发生了异常。我无法找到有关此异常的任何信息。我也无法在HashMap中找到带有别名Node的内部类。

[04/01/15 2:33 PM]: java.io.NotSerializableException: java.util.HashMap$Node
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
[04/01/15 2:33 PM]:     at java.util.ArrayList.writeObject(ArrayList.java:762)
[04/01/15 2:33 PM]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[04/01/15 2:33 PM]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[04/01/15 2:33 PM]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[04/01/15 2:33 PM]:     at java.lang.reflect.Method.invoke(Method.java:483)
[04/01/15 2:33 PM]:     at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
[04/01/15 2:33 PM]:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
[04/01/15 2:33 PM]:     at ab.server.data.ServerData.saveField(ServerData.java:157)
[04/01/15 2:33 PM]:     at ab.server.data.ServerData.processQueue(ServerData.java:195)
[04/01/15 2:33 PM]:     at ab.Server.lambda$0(Server.java:260)
[04/01/15 2:33 PM]:     at ab.Server$$Lambda$15/2011997442.run(Unknown Source)
[04/01/15 2:33 PM]:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[04/01/15 2:33 PM]:     at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
[04/01/15 2:33 PM]:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
[04/01/15 2:33 PM]:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
[04/01/15 2:33 PM]:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[04/01/15 2:33 PM]:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[04/01/15 2:33 PM]:     at java.lang.Thread.run(Thread.java:745)

这是正在序列化的类。

public class WellOfGoodWill implements Serializable {

    private static final long serialVersionUID = -3335621107999346623L;

    /**
     * The total number of winners possible for each draw
     */
    private static final int MAXIMUM_WINNERS = 3;

    /**
     * Compares the value of an entry
     */
    private static final Comparator<Entry<String, Integer>> HIGHEST_VALUE = Entry.comparingByValue();

    /**
     * Contains all of the entries for the week
     */
    private HashMap<String, Integer> entries = new HashMap<>();

    /**
     * Winners of the previous week
     */
    private Collection<Entry<String, Integer>> winners;

    /**
     * The date the week is over. The initial date is set.
     */
    private Date date = Misc.getFutureDate(2014, Calendar.DECEMBER, 28, 18, 0, 0);

    /**
     * Requests that an update be made on the entries variable.
     * @param player    the key being updated
     * @param amount    the amount being added 
     */
    public void update(String player, Integer amount) {
        if (!entries.containsKey(player)) {
            entries.put(player, amount);
        } else {
            int oldValue = entries.get(player);
            entries.replace(player, oldValue, oldValue + amount);
        }
        Server.getServerData().setWellOfGoodWill(this);
    }

    /**
     * Clears all entries in the map
     */
    public void clear() {
        entries.clear();
    }

    /**
     * Determines the weekly winner based on their contributions
     * @return  the winner
     */
    public Collection<Entry<String, Integer>> getSortedResults() {
        List<Entry<String, Integer>> list = new ArrayList<>(entries.entrySet());
        list.sort(HIGHEST_VALUE);
        Collections.reverse(list);
        return new ArrayList<>(list.subList(0, list.size() < MAXIMUM_WINNERS ? list.size() : MAXIMUM_WINNERS));
    }

    /**
     * The map containing all of the entries for the week
     * @return  the entries
     */
    public Map<String, Integer> getEntries() {
        return entries;
    }

    /**
     * The winner of the previous week
     * @return  the winner
     */
    public Collection<Entry<String, Integer>> getWinners() {
        return winners;
    }

    /**
     * Sets the new winner of the week
     * @param winner    the winner
     */
    public void setWinners(Collection<Entry<String, Integer>> winners) {
        this.winners = winners;
    }

    /**
     * The date the week started
     * @return  the date
     */
    public Date getDate() {
        return date;
    }

    /**
     * Sets the date of the week the event starts on
     * @param date  the date
     */
    public void setDate(Date date) {
        this.date = date;
    }

}

1 个答案:

答案 0 :(得分:0)

您尝试序列化为Serializable的课程是不够的,所有课程字段必须Serializable。特别是,大多数接口(包括CollectionMap.Entry)都没有实现Serializable

  

遍历图形时,可能会遇到不支持Serializable接口的对象。在这种情况下,将抛出NotSerializableException并将标识非可序列化对象的类。

根据经验,您应该始终使用显式可序列化类型作为可序列化类的字段(例如ArrayList,而不是ListCollection),否则您可能遇到此问题一种令人困惑的运行时故障。

您可以选择定义自定义writeObject()方法来处理非Serializable字段,或使用transient属性指示序列化程序应忽略该字段。

更多详情:https://docs.oracle.com/javase/8/docs/technotes/guides/serialization/index.html