1.存在的目的
个人认为序列化和反序列化存在的目的在于方便网络传输,资源(如图片,视频,音频等)本身是无法在网络上传播的,它们是以二进制序列的形式进行传播,其中序列化就是将我们可以看的懂的资源转化为我们看不懂的过程,而反序列化是将我们看不懂的二进制资源转化为我们可以看懂的图片等资源。
2.定义
序列化:将内存中的资源或Java对象转化为字节序列的过程。
反序列化:将字节序列转化回资源或Java对象的过程。
3.有关序列化的要求
序列化必须实现Serializable接口或者Externalizable接口。
4.有关Serializable和Externalizable的区别
1.Externalizable接口是Serializable接口的子类。
2.Serializable接口是一个标记接口,而Externalizable中有两个需要实现的方法,writeExternal()和readExternal(),其中writeExternal()方法把对象保存到输出流中,readExternal()方法把对象从输入流中进行读取。
3.Externalizable接口相比Serializable接口更加可控。
import java.io.Serializable;
public class Students implements Serializable {
private Students name;
}
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Students implements Externalizable {
private String name;
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String) in.readObject();
}
}
5.有关其使用
1.有关实现了Serializable接口的类的使用:通过正常的io进行操作即可(当然如果在类中自己定义了相关操作直接调用就可以了),其中被transient修饰的变量不能被序列化。
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Students students = new Students();
students.setName("hgw");
//输出操作
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("text.txt"));
outputStream.writeObject(students);
//输入操作
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("text.txt"));
System.out.println(objectInputStream.readObject());
}
}
import java.io.*;
public class Students implements Serializable {
private String name;
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.有关实现了Externalizable接口的类的使用:直接调用方法即可
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Students students = new Students();
students.setName("hgw");
students.writeExternal(new ObjectOutputStream(new FileOutputStream("text.txt")));
students.setName("aaa");
//此处我不知道怎么才能演示该效果,所以在此处改了个名字,然后在readExternal()方法中进行读取修改回,进行效果的演示
students.readExternal(new ObjectInputStream(new FileInputStream("text.txt")));
System.out.println(students);
}
}
import java.io.*;
public class Students implements Externalizable {
private String name;
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String) in.readObject();
}
}
6.有关serivalVersionUID
serivalVersionUID是一段字符,用于标识版本主要用于在反序列化时检查类的版本与序列化类的版本是否一致,来确保反序列化的对象和序列化的是兼容的(类似于人类的身份证吧,表明自己的信息,证明我是我)。serivalVersionUID即可以自己手写,也可以Java自己生成。
7.有关transient关键字
1.带有transient关键字的属性且该类实现了Serializable接口时,该属性不能被序列化。
2.transient只作用于实现了Serializable接口的类中的属性,不作用于实现了Externalizable的类的属性中。
3.静态属性一定不能被序列化,无论是否带有transient关键字。
8.参考文章
1.java序列化与反序列化详解_java序列化和反序列化-CSDN博客
2.java序列化、反序列化、serialVersionUID_object deserialization is used-CSDN博客
注:第一次写文章,如有不对的地方或者需要补充的地方请指出。