Java对象序列化是JDK的一项功能,经常被忽略。 当开发人员整理原型或编写概念证明时,只需将序列化的Java对象保存到本地文件系统中,而不是集成NoSQL数据库或关系系统以提供持久性,便可以节省大量时间。 这个ObjectOutputStream示例将演示将Java对象序列化和反序列化集成到您的应用程序中有多么容易。
Java序列化教程
在此Java序列化示例中,我们将同时使用ObjectOutputStream和ObjectInputStream来保存和检索简单JavaBean的状态。 POJO将在本地文件系统中进行序列化和反序列化。
对于此Java序列化教程,我们将创建一个简单的Score类。 该课程将模拟剪刀石头布游戏的得分,其属性将计算已发生的胜利,失败和平局的数量。 将有用于属性的getter方法,但不会有setter。 得分类维护的获胜,失败和平局的数量一次只能增加一个,因此Java序列化对象将使用名为WinsWins,IncreaseTies和IncreaseLosses的方法来代替setter方法。 完整的类编码如下:
/* Java serialization example class */
package com.mcnz.serialization.tutorial;
import java.io.*;
public class Score implements java.io.Serializable {
private static final long serialVersionUID = 1L;
int wins, losses, ties;
public Score() {}
/* No need for setters and getters in this
* Java object serialization tutorial. We
* will 'punch up' the class used for the
* ObjectOutputStream example at the end
* of this Java object serialization example.*/
}
/* End of Java serialization tutorial class */
Java对象序列化
在执行Java对象序列化之前,首先需要创建该类的实例。 调用要序列化的类的构造函数即可实现此目的。
Score score = new Score();
然后,您需要确定序列化实例的目的地。 Java对象序列化会以文件系统为目标吗? Java对象会在网络上序列化吗? 序列化的Java对象是否将交付给外部系统。 在这种情况下,我们将执行基于文件系统的Java对象序列化。 这意味着我们必须创建FileOutputStream的实例并将其指向文件系统上的文件。
FileOutputStream fileOut = new FileOutputStream("C:\\temp\\score.ser");
如上面的Java代码所示,序列化的Java实例的状态将写入名为score.ser的文件,该文件位于C:驱动器根目录下的临时目录中。 在运行示例之前,必须首先创建此文件,以免程序抛出运行时异常。
ObjectOutputStream示例
创建FileOutputStream之后,我们只需将实例传递给ObjectOutputStream的构造函数即可。 FileOutputStream和ObjectOutputStream的组合将允许Java对象序列化在文件级别进行。
ObjectOutputStream out = new ObjectOutputStream(fileOut);
创建了ObjectOutputStream的初始化后,剩下要做的就是在实例上执行Java序列化。 将score对象作为参数传递给ObjectOutputStream的writeObject方法以实现此目的:
out.writeObject(score);
关闭ObjectOutputStream
Java对象序列化完成后,可以关闭ObjectOutputStream和FileOutputStream。
out.close();
fileOut.close();
添加必需的catch块之后,完整的ObjectOutputStream示例如下所示:
/* Start of Java serialization example class */
class JavaSerializationExample {
public static void main (String args[]) {
Score score = new Score();
saveScore(score);
}
public static void saveScore(Score score) {
try {
FileOutputStream fileOut = new FileOutputStream("C:\\score01.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(score);
out.close();
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/* End of Java serialization tutorial class */
Java反序列化示例
当然,Java对象序列化只是工作的一半。 另一半是Java对象反序列化,我们通过FileInputStream和ObjectInputStream完成。
在Java对象反序列化中执行的第一步是声明要初始化的Score类的空白实例。 因为我们期望JVM执行Java反序列化,所以我们不需要创建Score类的实例,而是声明一个实例,并等待Java反序列化过程对其进行初始化。
Score score = null;
基于文件的ObjectInputStream示例
下一步是将FileInputStream的实例指向序列化过程创建的文件。 然后,该FileInputstream被传递到ObjectInputStream的构造函数中。
FileInputStream fileIn = new FileInputStream("C:\\score.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
初始化ObjectInputStream后,只需通过调用ObjectInputStream的readObject方法即可进行Java反序列化:
score = (Score) in.readObject();
Java反序列化完成后,可以关闭ObjectInputStream和FileInputStream。
in.close();
fileIn.close();
全部放在一起后,代码如下所示:
/* Java object deserialization example class */
class JavaDeserializationExample {
public static void main (String args[]) {
Score score = new Score();
saveScore(score);
}
public static Score getScore() {
Score score = null;
try {
FileInputStream fileIn = new FileInputStream("C:\\score01.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
score = (Score) in.readObject();
in.close();
fileIn.close();
} catch (Exception e) {
System.err.println("\nError creating Score object. None exists?\n"
+ e.getMessage() + e.getClass());
}
if (score == null) {
score = new Score();
JavaSerializationExample.saveScore(score);
}
return score;
}
}
/* End of Java object deserialization tutorial class */
您会注意到在getScore()方法的末尾,将进行检查以查看score实例是否仍为null。 如果是这样,则Java反序列化失败,这很可能是由于Score类的实例最初从未经历过Java对象序列化的事实。 为了解决这种可能性,如果实例确实返回空值,则会创建一个新实例并进行序列化。 将来反序列化此实例的尝试将成功。
就是这样。 这个ObjectInputStream和ObjectOutputStream示例演示执行Java对象序列化和反序列化的过程是多么容易。
Java对象序列化示例源代码
该Java序列化教程的完整代码如下。 该代码使用一个公共类和两个非公共类,所有这些都可以编写并保存在一个名为Score.java的Java文件中。
package com.mcnz.ioc.example;
import java.io.*;/* The Java serialization tutorial class. */
/* Notice we have added getters and increase methods to the
* class used to demonstrate Java object serialization. We left
* these methods out earlier to keep the ObjectOutputStream example
* more concise. */
public class Score implements java.io.Serializable {
private static final long serialVersionUID = 1L;
int wins, losses, ties;
public Score() {}
public void increaseWins() { this.wins++; }
public void increaseLosses() { this.losses++; }
public void increaseTies() { this.ties++; }
public void reset() { wins=losses=ties=0; }
public int getWins() { return wins; }
public int getLosses() { return losses; }
public int getTies() { return ties; }
}
/* End of Java serialization tutorial class */
/* ObjectOutputStream Example */
class JavaSerializationExample {
public static void main (String args[]) {
Score score = new Score();
score.increaseWins();
score.increaseTies();
saveScore(score);
System.out.println(score.getTies());
}
public static void saveScore(Score score) {
try {
FileOutputStream fileOut = new FileOutputStream("C:\\temp\\score.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(score);
out.close();
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/* End of ObjectOutputStream example tutorial */
/* ObjectInputStream Example */
class JavaDeserializationExample {
public static void main (String args[]) {
Score score = null;
score = JavaDeserializationExample.getScore();
System.out.println(score.getWins());
System.out.println(score.getLosses());
System.out.println(score.getTies());
}
public static Score getScore() {
Score score = null;
try {
FileInputStream fileIn = new FileInputStream("C:\\temp\\score.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
score = (Score) in.readObject();
in.close();
fileIn.close();
} catch (Exception e) {
System.err.println("\nError creating Score object. None exists?\n"
+ e.getMessage() + e.getClass());
}
if (score == null) {
score = new Score();
JavaSerializationExample.saveScore(score);
}
return score;
}
}
/* End of ObjectInputStream example tutorial */