我想保存我在程序中生成的对象。重新启动后,应用程序应自动加载数组中的所有对象。我想将它们写入文件并在重新启动后解析它们。还有其他比手工更聪明的可能性吗?谢谢
8 回答
是的,您正在寻找的概念称为序列化。Sun这里有一个很好的教程。
这个想法是你想要持久化的类必须实现 Serializable 接口。之后,您使用 java.io.ObjectOutputStream.writeObject() 将对象写入文件并使用 java.io.ObjectInputStream.readObject() 将其读回。
你不能序列化所有东西,因为有些东西序列化没有意义,但你可以解决它们。这是一个引用:
Java序列化的基本机制使用起来很简单,但是还有一些东西需要了解。如前所述,只有标记为 Serializable 的对象才能被持久化。java.lang.Object 类不实现该接口。因此,并非Java中的所有对象都可以自动持久化。好消息是它们中的大多数——比如 AWT 和 Swing GUI 组件、字符串和数组——都是可序列化的。
另一方面,某些系统级类,如 Thread、OutputStream 及其子类和 Socket 是不可序列化的。确实,如果它们是,那将没有任何意义。例如,在我的 JVM 中运行的线程将使用我系统的内存。坚持它并试图在你的 JVM 中运行它根本没有意义。关于 java.lang.Object 未实现 Serializable 接口的另一个重要点是,您创建的任何仅扩展 Object(而没有其他可序列化类)的类都是不可序列化的,除非您自己实现该接口(如前面的示例所做的那样)。
这种情况提出了一个问题:如果我们有一个包含 Thread 实例的类怎么办?在那种情况下,我们可以持久化这种类型的对象吗?答案是肯定的,只要我们通过将我们类的 Thread 对象标记为瞬态来告诉序列化机制我们的意图。
您可以使用Berkeley DB PersistentMap
类将 ( Serializable
) 对象保存在Map
实现(缓存)中,该实现(缓存)将它们保存到文件中。它使用起来非常简单,意味着您不必担心将什么保存在哪里。
序列化需要注意的三点:
- 您将如何应对架构更改(即更改您的类所包含的数据 - 例如添加一个新字段)
- 如果您的文件损坏了怎么办?取决于您的程序存储需要的可靠性,这将影响您对如何保存对象隐含包含的数据的决定。请记住,您始终可以使用MySQL等关系数据库,然后将这些数据转换为您的对象
- 您是否需要能够查看或查询程序之外的数据?如果您想回答一些简单的问题,例如“有多少对象具有属性 X?”,该怎么办?如果您使用过(关系)数据库,则很容易做到;如果您已将内容序列化为文件,那就不那么容易了!
您可能想查看 Effective Java 了解有关序列化的一些问题。这些通常是高级的,但如果此功能是您应用的核心部分,您需要提前了解它们。
示例包括安全问题、继承,以及最重要的是公开“冻结”API 并实现它的潜力(例如,跨软件版本)。同样,这些都是先进的,不应该阻止你本身。
java.io.Object[Input/Output]Stream 是您需要查看的两个类。
您希望保存到文件的任何类都需要实现 java.io.Serializable 接口。
您可能还想考虑使用 XML 编码,在我看来,这似乎比序列化更持久。使用java.beans.XMLEncoder/XMLDecoder
类。
我没用过,但谷歌代码最近发布了protobuf 。
我同意 mjlee 的观点,即来自 Google 的 Protocol Buffers是一种比原始序列化方式更好的存储对象方式。看看,你会喜欢的。
我想知道为什么没有人提到JSON,例如Jackson JSON 序列化器。