一、前言
当Java类对象需要读写磁盘或网络传输的时候,需要实现Serializable接口变为一个可序列化对象,同时,要提供具体的序列化方法,如最常用的Java IO序列化,本文讲述序列化/反序列化的相关知识,由浅入深。
二、JavaBean的序列化和反序列化
2.1 socket通信中的序列化
可序列化对象:Java语言中,当对象用于读写磁盘(内存–磁盘)或读写网络(内存–网络),这个对象要求是可序列的,即实现Serializable接口。
序列化两种场景:序列化就是写入磁盘文件或写入网络,将对象转换为二进制流;反序列化就是从磁盘文件中读出或从网络中接收,将二进制流转换为对象。
序列化实现方式:序列化的方式有很多,Java中可以通过输入输出流来序列化和反序列化,其他的,还包括json序列化、xml序列化。评价不同的序列化方式,包括序列化后二进制流大小和该序列化方式是否可以跨平台。
新建两个maven工程 server client ,在Socket 通信中传递JavaBean对象,该Bean类必须实现Serializable接口,变为一个可序列化类;
新建三个类,User类作为JavaBean类,实现Serializable接口,用于Socket网络传输,ServerSocketDemo作为socket服务端类,ClientSocketDemo作为socket客户端类。
public class User implements Serializable {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class ServerSocketDemo {
static ServerSocket serverSocket;
public static void main(String[] args) throws Exception {
serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
ObjectInputStream objectOutputStream = new ObjectInputStream(socket.getInputStream());
User user = (User) objectOutputStream.readObject();
System.out.println(user);
}
}
public class ClientSocketDemo {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 8080);
User user = new User();
user.setName("Mic");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(user);
}
}
先运行服务端程序,再运行客户端程序,连接服务端socket,给服务端发送User类对象,服务端收到,打印出来:
2.2 序列化封装为工具方法
现在我们新建一个User4,如下:
public class User4 implements Serializable {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
封装两个工具方法,序列化和反序列化:
public interface ISerialize {
public <T> byte[] toolFunction_serialize(T obj) throws Exception;
public <T> T toolFunction_deserialize(byte[] data) throws Exception;
}
public class Utils_JavaSerialize implements ISerialize {
// 序列化工具方法 输入是对象 输出是byte数组
public <T> byte[] toolFunction_serialize(T obj) throws Exception{
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
return byteArrayOutputStream.toByteArray();
}
// 反序列化工具方