基础知识及作用
Java序列化和反序列化是Java编程中非常重要的概念,它们是Java语言中实现对象持久化的重要手段。探讨Java序列化和反序列化的概念、作用、实现方法以及常见问题和解决方法。
一、Java序列化和反序列化的概念
Java序列化和反序列化是Java语言中实现对象持久化的重要手段。Java序列化是指将Java对象转换为字节序列的过程,而Java反序列化则是指将字节序列转换为Java对象的过程。Java序列化和反序列化的实现方法有多种,除了我上课学习的Java原生序列化之外,在课程外还有其它的序列化方法:JSON序列化、XML序列化等。
其中Java原生序列化其实就是对IO流中的对象流进行操作
ObjectInputStream——从输入流中读取字节序列,反序列化为对象。
ObjectOutputStream——将指定对象进行序列化,把字节序列写到目标输出流中。
二、Java序列化和反序列化的作用
Java序列化和反序列化的主要作用是实现对象的持久化。在Java编程中,对象的持久化是指将对象保存到文件或数据库中,以便在程序重新启动后能够恢复对象的状态。Java序列化和反序列化可以将Java对象转换为字节序列,从而实现对象的持久化。通过Java序列化和反序列化,我们可以实现以下功能:
- 将Java对象保存到文件或数据库中,以便在程序重新启动后能够恢复对象的状态。
- 将Java对象通过网络传输,以便在不同的机器上共享数据。
操作示例
三、Java序列化和反序列化的实现方法
- Java原生序列化
Java原生序列化是Java语言中最常用的序列化和反序列化方法。Java原生序列化可以将Java对象转换为字节序列,并将字节序列保存到文件或数据库中。Java原生序列化的实现方法非常简单,只需要在Java对象上添加Serializable接口,然后使用ObjectOutputStream类将Java对象转换为字节序列即可。以下是Java原生序列化的示例代码:
我定义一个array类作为序列化的对象
package comt.流.序列化;
import java.io.Serializable;
public class array implements Serializable {
private String name;
private String age;
private String ID;
public array(){}
public array(String name,String age,String ID){
this.age=age;
this.name=name;
this.ID=ID;
}
public void setName(){
this.name= name;
}
public void setAge(){
this.age=age;
}
public void setID(){
this.ID=ID;
}
public String getName() {
return name;
}
public String getAge() {return age;}
public String getID() {
return ID;
}
public String toString(){
return name+age+ID;
}
}
然后写一个ob类作为我们进行序列化和反序列化操作的地方,将序列化和反序列化写在一个方法里面,供我们在主类中调用。
package comt.流.序列化;
import java.io.*;
public class ob implements Serializable {
private static final long serialVersionUID = -4514367344756885278L;
public static void xuliehua(array ay){
File file=new File("D:/IDEA-java/src/comt/流/序列化/a.txt");
FileOutputStream FOS = null;
ObjectOutputStream OOS =null;
{
try {
FOS = new FileOutputStream(file);
try {
OOS =new ObjectOutputStream(FOS);
OOS.writeObject(ay);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (OOS != null) {
OOS.close();
}
if (FOS != null) {
FOS.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
FileInputStream FS =null;
ObjectInputStream OIS =null;
{
try {
FS =new FileInputStream(file);
try {
OIS = new ObjectInputStream(FS);
try {
array ary =new array();
ary=(array)(OIS.readObject());
System.out.println(ary);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
try {
OIS.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
FS.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在主类中,我实例化array,然后作为参数传入方法。
package comt.流.序列化;
import static comt.流.序列化.ob.xuliehua;
public class operate {
public static void main(String[] args) {
array ay =new array("zhang","18","2002918");
xuliehua(ay);
}
}
运行之后,也成功的输出了我实例化的数据。
遇到的问题
四、Java序列化和反序列化我遇见的常见问题。
在我上面的示例中,我当时为了比较两个输出方法有什么不同,我写了两个输出方法:
System.out.println(o);//这一行在控制台正常打印了出来
System.out.println((array) OIS.readObject());//为什么这行会报异常,异常的追踪栈打印最终显示在这一行`
运行时报了EOFException,我查了这个异常来表示输出流到了文件的末尾.
当时我的逻辑是如此:我已经序列化了数据进去,那么序列化的数据就在那里,那么我多次反序列化也可以.
我将问题放在了问答区,然后根据问答区的思路,和一些深入讲解的博客.
然后理解到了以下东西:
1.EOFException这个异常是正常的,就像字节流文件读取到最后时返回的是-1,只不过对象流是直接抛出异常.
2.objectRead()这个方法里面有一个像指针的东西,我第一次使用后文件指针就到了文件末尾,我第二次没有重新打开读取文件,文件指针还在末尾,所以就抛了异常.