序列化
原理无非将对象压缩成字符流,需要的时候再取出来;
这种情况在分布式用的比较多,类似的Xml和Json也可以实现这种效果;
下面放一个Java序列化的例子
1.创建实例化对象
package com.bean;
import java.io.Serializable;
import java.util.List;
/**
* @author: jane
* @CreateTime: 2020/5/11
* @Description:
*/
public class MyProto implements Serializable {
int userID;
String userName;
List hobby;
public MyProto(int userID, String userName, List hobby){
this.userID = userID;
this.userName = userName;
this.hobby = hobby;
}
@Override
public String toString() {
return "MyProto{" +
"userID=" + userID +
", userName='" + userName + '\'' +
", hobby=" + hobby +
'}';
}
}
如果有不希望被序列化的属性,可以加上transient;
2.编写测试
package com.serializable;
import com.bean.MyProto;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author: jane
* @CreateTime: 2020/5/11
* @Description:
*/
public class SerializableTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
List hobby = new ArrayList<>();
hobby.add("Programming");
hobby.add("Reading");
hobby.add("Playing Games");
MyProto proto = new MyProto(666, "Jane", hobby);
System.out.println("Before encode:"+proto.toString());
FileOutputStream fos = new FileOutputStream(new File("src/main/resources/serial.out"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(proto);
FileInputStream fis = new FileInputStream(new File("src/main/resources/serial.out"));
ObjectInputStream ois = new ObjectInputStream(fis);
MyProto proto2 = (MyProto)ois.readObject();
System.out.println("After decode:"+proto2.toString());
}
}
3.输出结果,符合预期
Before encode:MyProto{userID=666, userName='Jane', hobby=[Programming, Reading, Playing Games]}
After decode:MyProto{userID=666, userName='Jane', hobby=[Programming, Reading, Playing Games]}
Protobuf
Protobuf也是用于序列化的,而且Protobuf的效率比较高,适合常见语言;
Java自带的Serializable就比较专一了。。。
下面演示Windows版的例子
1.下载
里面的protoc.exe是关键
2.编写MyProto.proto
option java_package = "com.protobuf";
option java_outer_classname = "MyProtoName";
message MyProto{
required int32 userID = 1;
required string userName = 2;
repeated string hobby = 3;
}
3.Cmd下,通过Protobuf生成Java文件
protoc.exe --java_out=.\ .\MyProto.proto
4.把生成的Java文件放到项目对应位置,编写测试
package com.protobuf;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @author: jane
* @CreateTime: 2020/5/11
* @Description:
*/
public class ProtoTest {
public static void main(String[] args) throws InvalidProtocolBufferException {
MyProtoName.MyProto proto = create();
System.out.println("Before encode:");
System.out.println(proto.toString());
MyProtoName.MyProto proto2 = decode(encode(proto));
System.out.println("After decode:");
System.out.println(proto2.toString());
System.out.println(proto.equals(proto2));
}
private static MyProtoName.MyProto create(){
MyProtoName.MyProto.Builder builder = MyProtoName.MyProto.newBuilder();
builder.setUserID(777);
builder.setUserName("Jayying");
List hobby = new ArrayList<>();
hobby.add("Programming");
hobby.add("Reading");
hobby.add("Playing Games");
builder.addAllHobby(hobby);
return builder.build();
}
private static byte[] encode(MyProtoName.MyProto proto){
return proto.toByteArray();
}
private static MyProtoName.MyProto decode(byte[] code) throws InvalidProtocolBufferException {
return MyProtoName.MyProto.parseFrom(code);
}
}
5.结果输出,符合预期
Before encode:
userID: 777
userName: "Jayying"
hobby: "Programming"
hobby: "Reading"
hobby: "Playing Games"
After decode:
userID: 777
userName: "Jayying"
hobby: "Programming"
hobby: "Reading"
hobby: "Playing Games"
true