**
序列化
**在Java中,Serializable 是一个标记接口,它用于标识类的对象可以被序列化。序列化是将对象的状态转换为字节流的过程,以便将其保存到文件、数据库中,或通过网络传输到其他计算机。反序列化则是将字节流还原为对象的状态。
实现 Serializable 接口的类可以将其对象转换为字节流,从而可以在不同的Java虚拟机之间传输对象,或者将对象持久化到磁盘。以下是一些关于为什么要实现 Serializable 接口的主要用途:
对象持久化: 将对象的状态保存到磁盘上,以便在程序重新启动时能够恢复对象的状态。这在应用程序的数据持久化和恢复方面非常有用。
分布式系统: 在网络上传输对象,使得在不同的计算机之间进行通信变得更加容易。通过序列化,可以将对象转换为字节流,然后通过网络传输,接收方再进行反序列化还原为对象。
缓存: 在某些情况下,可以将对象序列化后存储在缓存中,以提高数据的读取速度。当需要时,可以从缓存中快速反序列化获取对象。
要实现 Serializable 接口,只需要在类的声明中添加 implements Serializable,并且确保类的所有成员变量也是可序列化的。例如:
import java.io.Serializable;
public class MyClass implements Serializable {
private int myInt;
private String myString;
// 构造函数、方法等...
// Getter和Setter方法...
}
需要注意的是,当一个类实现 Serializable 接口时,建议加上一个版本号(serialVersionUID),以便在后续类的修改中保持兼容性。这样可以防止在反序列化时由于类的结构变化而导致的版本不一致问题。
例如:
private static final long serialVersionUID = 1L;
1L:L代表long类型,如果不加L则是int类型
反序列化
1、先将对象写进文件中
2、反序列将对象读取出来并输出
3、如果我故意把写入时候的序列化和读取时序列化改成不一样,将会导致读取失败并且报错
Exception in thread “main” java.io.InvalidClassException: djava.School; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
下面是完整代码
package djava;
import java.io.*;
class School implements Serializable {
private String name;
private String location;
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", location='" + location + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public School(String name, String location) {
this.name = name;
this.location = location;
}
private static final long serialVersionUID = 2L;
}
public class SerializableDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
readObj();
}
public static void readObj() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("test.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
School sch = (School) in.readObject();
in.close();
fileIn.close();
System.out.println(sch);
}
public static void printObj() throws IOException {
School sch = new School("南京大学", "南京");
FileOutputStream fou = new FileOutputStream("test.ser");
ObjectOutputStream out = new ObjectOutputStream(fou);
out.writeObject(sch);
out.close();
fou.close();
}
}
- Externalizable 接口
Externalizable 接口是 Java 序列化机制的一种替代方案。与 Serializable 接口不同,Externalizable 要求实现类提供自己的序列化和反序列化逻辑,而不是依赖默认的序列化机制
import java.io.*;
public class MyClass implements Externalizable {
private int data;
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(data);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
data = in.readInt();
}
}
常用的一些序列化协议
Hessian、kryo[k’raɪəʊ] 、Gson