1. 什么是序列化与反序列化?
序列化就是将代码中的对象的某一个状态转化成字节数组的过程,也就是转化成二进制文件的过程。反序列化与之相反。
2. 为什么要进行序列化?
在将对象存储在文件中或者通过网络进行传输的时候,对象是不能直接存储和传输的,所以要将它序列化为对应的二进制代码。
3. 实现序列化的常用方式有哪些?
使用Java的序列化协议(实现Serializable接口)
使用Google的序列化协议(Protocol buff)
4.两种序列化方法的区别有哪些?
首先来看Java序列化协议的序列化过程
/**
* @Description 对象实体类实现Serializable接口
*/
public class User implements Serializable {
private int id;
private String name;
private String password;
constructor and getters、setters...
}
/**
* 对象反序列化过程
* @param bytes
* @throws IOException
* @throws ClassNotFoundException
*/
public static void toUser(byte[] bytes) throws IOException, ClassNotFoundException {
ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
User user = (User) inputStream.readObject();
System.out.println("id: " + user.getId());
System.out.println("name: " + user.getName());
System.out.println("password: " + user.getPassword());
}
/**
* 对象序列化过程
* @return
* @throws IOException
*/
public static byte[] toBytes() throws IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(stream);
User user = new User(1,"admin", "123");
outputStream.writeObject(user);
byte[] bytes = stream.toByteArray();
System.out.println(Arrays.toString(bytes));
return bytes;
}
[-84, -19, 0, 5, 115, 114, 0, 13, 99, 111, 109, 46, 106, 97, 118, 97, 46, 85, 115, 101, 114, 98, 0, -44, -50, -126, 35, -58, 126, 2, 0, 3, 73, 0, 2, 105, 100, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 0, 8, 112, 97, 115, 115, 119, 111, 114, 100, 113, 0, 126, 0, 1, 120, 112, 0, 0, 0, 1, 116, 0, 5, 97, 100, 109, 105, 110, 116, 0, 3, 49, 50, 51]
id: 1
name: admin
password: 123
//user.proto 文件
option java_package = "com.proto";
option java_outer_classname = "UserModule";
message User {
required int32 id = 1;
required string name = 2;
required string password = 3;
}
/**
* 反序列化
* @param bytes
* @throws InvalidProtocolBufferException
*/
public static void toUser(byte[] bytes) throws InvalidProtocolBufferException {
//反序列化为对象
UserModule.User user = UserModule.User.parseFrom(bytes);
System.out.println("id: " + user.getId());
System.out.println("username: " + user.getName());
System.out.println("password: " + user.getPassword());
}
/**
* 序列化
* @return
*/
public static byte[] toBytes() {
//获取一个PBUser构造器
UserModule.User.Builder builder = UserModule.User.newBuilder();
builder.setId(1).setName("admin").setPassword("123");
UserModule.User user = builder.build();
byte[] bytes = user.toByteArray();
System.out.println(Arrays.toString(bytes));
return bytes;
}
### 结果
[8, 1, 18, 5, 97, 100, 109, 105, 110, 26, 3, 49, 50, 51]
id: 1
username: admin
password: 123
- Java的序列化包含了类名,字段名,字段属性,字段值等信息,而Protocolbuf只包含了字段值,其余信息是通过配置文件表示的。
- Protocolbuf存取字节数组的方式采用的可伸缩性的方法。例如对int字段的存取,Java序列化是固定长度的,比如int就是四个字节