Java 使用自定义序列化对象序列化HashMap

Java 使用自定义序列化对象序列化HashMap,java,serialization,java-8,Java,Serialization,Java 8,我在ActionHandler类中声明HashMap: public class ActionHandler { private HashMap<Cooldown, Long> cooldowns = new HashMap<Cooldown, Long>(); public void disInit(Main main) throws FileNotFoundException, IOException{ String path = m

我在ActionHandler类中声明HashMap:

public class ActionHandler {
    private HashMap<Cooldown, Long> cooldowns = new HashMap<Cooldown, Long>();

    public void disInit(Main main) throws FileNotFoundException, IOException{
        String path = main.getDataFolder() + File.separator + "cooldowns.dat";
        File serialize = new File(path);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(serialize));
        oos.writeObject(cooldowns);
        oos.flush();
        oos.close();
        serialize.createNewFile();
    }
}
每当插件序列化文件(使用disit)时,控制台就会抛出此错误。我很兴奋,因为我已经为我的冷却课程实现了Serializable

[21:16:29 WARN]: java.io.NotSerializableException: com.gmail.ketracoder.vts.Main

[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeObject0(ObjectOutputS
tream.java:1184)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.defaultWriteFields(ObjectO
utputStream.java:1548)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeSerialData(ObjectOutp
utStream.java:1509)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeOrdinaryObject(Object
OutputStream.java:1432)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeObject0(ObjectOutputS
tream.java:1178)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.defaultWriteFields(ObjectO
utputStream.java:1548)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeSerialData(ObjectOutp
utStream.java:1509)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeOrdinaryObject(Object
OutputStream.java:1432)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeObject0(ObjectOutputS
tream.java:1178)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeObject(ObjectOutputSt
ream.java:348)
[21:16:29 WARN]:        at java.util.HashMap.internalWriteEntries(HashMap.java:1
776)
[21:16:29 WARN]:        at java.util.HashMap.writeObject(HashMap.java:1354)
[21:16:29 WARN]:        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native M
ethod)
[21:16:29 WARN]:        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMet
hodAccessorImpl.java:62)
[21:16:29 WARN]:        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Deleg
atingMethodAccessorImpl.java:43)
[21:16:29 WARN]:        at java.lang.reflect.Method.invoke(Method.java:483)
[21:16:29 WARN]:        at java.io.ObjectStreamClass.invokeWriteObject(ObjectStr
eamClass.java:988)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeSerialData(ObjectOutp
utStream.java:1496)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeOrdinaryObject(Object
OutputStream.java:1432)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeObject0(ObjectOutputS
tream.java:1178)
[21:16:29 WARN]:        at java.io.ObjectOutputStream.writeObject(ObjectOutputSt
ream.java:348)
[21:16:29 WARN]:        at com.gmail.ketracoder.vts.Shop.ActionHandler.disInit(A
ctionHandler.java:39)
[21:16:29 WARN]:        at com.gmail.ketracoder.vts.Main.onDisable(Main.java:165
)
[21:16:29 WARN]:        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlug
in.java:323)
[21:16:29 WARN]:        at org.bukkit.plugin.java.JavaPluginLoader.disablePlugin
(JavaPluginLoader.java:359)
[21:16:29 WARN]:        at org.bukkit.plugin.SimplePluginManager.disablePlugin(S
implePluginManager.java:424)
[21:16:29 WARN]:        at org.bukkit.plugin.SimplePluginManager.disablePlugins(
SimplePluginManager.java:417)
[21:16:29 WARN]:        at org.bukkit.craftbukkit.v1_8_R1.CraftServer.disablePlu
gins(CraftServer.java:334)
[21:16:29 WARN]:        at net.minecraft.server.v1_8_R1.MinecraftServer.stop(Min
ecraftServer.java:430)
[21:16:29 WARN]:        at net.minecraft.server.v1_8_R1.MinecraftServer.run(Mine
craftServer.java:561)
[21:16:29 WARN]:        at java.lang.Thread.run(Thread.java:745)
我唯一一次在HashMap中放入内容是在调用:

private void setCooldown(Player player, int slot, Main main, Shop shop){
        String playerName = player.getName();
        Cooldown cooldown = new Cooldown(playerName, shop);
        cooldowns.put(cooldown, System.currentTimeMillis());
}
冷却
类是导致问题的原因

否,
Main
类是导致问题的原因,如异常所示:

java.io.NotSerializableException: com.gmail.ketracoder.vts.Main
显然,
Cooldown
Main
的一个内部类,因此它保留了对封闭对象的引用,该对象不可序列化。将其设为静态类或外部类

注意:在调用它的地方调用
createNewFile()
,将生成一个长度为零的文件。您不需要在任何地方这样做:
newfileoutputstream(…)
已经这样做了。把它拿走

冷却
类是导致问题的原因

否,
Main
类是导致问题的原因,如异常所示:

java.io.NotSerializableException: com.gmail.ketracoder.vts.Main
显然,
Cooldown
Main
的一个内部类,因此它保留了对封闭对象的引用,该对象不可序列化。将其设为静态类或外部类

注意:在调用它的地方调用
createNewFile()
,将生成一个长度为零的文件。您不需要在任何地方这样做:
newfileoutputstream(…)
已经这样做了。把它拿走

冷却
类是导致问题的原因

否,
Main
类是导致问题的原因,如异常所示:

java.io.NotSerializableException: com.gmail.ketracoder.vts.Main
显然,
Cooldown
Main
的一个内部类,因此它保留了对封闭对象的引用,该对象不可序列化。将其设为静态类或外部类

注意:在调用它的地方调用
createNewFile()
,将生成一个长度为零的文件。您不需要在任何地方这样做:
newfileoutputstream(…)
已经这样做了。把它拿走

冷却
类是导致问题的原因

否,
Main
类是导致问题的原因,如异常所示:

java.io.NotSerializableException: com.gmail.ketracoder.vts.Main
显然,
Cooldown
Main
的一个内部类,因此它保留了对封闭对象的引用,该对象不可序列化。将其设为静态类或外部类


注意:在调用它的地方调用
createNewFile()
,将生成一个长度为零的文件。您不需要在任何地方这样做:
newfileoutputstream(…)
已经这样做了。只需删除它。

如果您从最深的stacktrace条目开始寻找非
java.io
相关方法,您将找到
java.util.HashMap.writeObject
,它负责存储
映射中包含的对象。如果在此过程中遇到不可序列化的对象,如
com.gmail.ketracoder.vts.Main
,很明显,您必须在尝试序列化之前将其作为键或值(或者两者)放入映射中

如果要序列化映射,映射中包含的所有对象都必须是可序列化的。与AWT组件上的侦听器不同,没有跳过不可序列化的对象


但请注意,你所做的是危险的。如果映射中包含
Main
的实例,而
Main
将反过来引用映射(我猜是从类名中得到的),那么就有一个循环引用。虽然序列化原则上适用于循环对象图,但当它们与
HashMap
s结合使用时,序列化将非常脆弱。还原映射时,
HashMap
需要重新灰化所有元素,这可能会导致循环对象图中对不完整对象调用
hashCode
equals

如果从最深的stacktrace条目开始查找与java.io
无关的方法,您将找到负责存储
映射中包含的对象的
java.util.HashMap.writeObject
。如果在此过程中遇到不可序列化的对象,如
com.gmail.ketracoder.vts.Main
,很明显,您必须在尝试序列化之前将其作为键或值(或者两者)放入映射中

如果要序列化映射,映射中包含的所有对象都必须是可序列化的。与AWT组件上的侦听器不同,没有跳过不可序列化的对象


但请注意,你所做的是危险的。如果映射中包含
Main
的实例,而
Main
将反过来引用映射(我猜是从类名中得到的),那么就有一个循环引用。虽然序列化原则上适用于循环对象图,但当它们与
HashMap
s结合使用时,序列化将非常脆弱。还原映射时,
HashMap
需要重新灰化所有元素,这可能会导致循环对象图中对不完整对象调用
hashCode
equals

如果从最深的stacktrace条目开始查找与java.io
无关的方法,您将找到负责存储
映射中包含的对象的
java.util.HashMap.writeObject
。如果在此过程中遇到不可序列化的对象,如
com.gmail.ketracoder.vts.Main
,很明显,您必须在尝试序列化之前将其作为键或值(或者两者)放入映射中

如果要序列化映射,映射中包含的所有对象都必须是可序列化的。与AWT组件上的侦听器不同,没有跳过非
S