【发布时间】:2012-04-17 15:18:18
【问题描述】:
我有一个带有 JList 的 Swing 应用程序,它与自定义列表模型一起使用。
模型有一个 ArrayList 来存储使用的对象。情况如下:
关闭应用程序后,listmodel 中的所有对象都被序列化(默认情况下,该类只实现Serializable),并通过ObjectOutputStream 写入文件。当应用程序启动时,从文件中读取所有对象并再次存储在我的自定义ListModel 中。
我正在尝试添加一项功能,让用户也可以从他指定的文件中导入对象。另一个类中的静态方法从文件中读取所有对象,并在ArrayList 中返回它们。然后我在MainForm 类中使用for-each 循环将返回的ArrayList 中的每个对象存储在ListModel 中。在循环中,我想检查ListModel 是否已经包含某个对象,但这不起作用。
在代码中,我正在执行以下操作:
for(MyObject o: readObjects) {
if(!myListModel.contains(o)) //listmodel just calls contains() on its ArrayList
myListModel.addElement(o);
}
但是,即使对象已经在 ArrayList 中(我一直从同一个文件中导入对象),它们仍然会被添加。
问题是,为什么反序列化后对象不再相等,有没有办法比较它们?
【问题讨论】:
-
您是否在您的对象类中覆盖
equals()方法? -
@MarioDeSchaepmeester 如果您不覆盖 equals,则 contains 将测试引用相等性(Object 类中 equals 的默认行为)。即使不使用序列化,如果您创建 2 个具有相同字段的对象,上面的代码也不会达到您的预期(例如:
list.add(new MyObject());和list.contains(new MyObject())将返回 false)。 -
是的,当反序列化时,您的对象将被重新创建并具有新的引用。如果您不覆盖
equals()方法,则它是刚刚检查的引用。 (我认为) -
@assylias,你们中的任何一个人能否解释一下为了在覆盖方法时成功比较 2 个对象应该做什么?有什么最佳做法吗?我已经看到人们在他们的课程中放置了序列号或其他东西,这是我应该使用的吗?我以前没用过这种东西……
-
我认为 serialUID 与此无关。如果您使用的是 Eclipse 之类的 IDE,您可以要求它自动覆盖
equals()。基本上,您必须选择对象的哪些字段用于比较两个对象。
标签: java object serialization equals