目录
序列化与反序列化
序列化与分布式通信关系
通过 序列化+反序列化+网络 的结合
,不同的应用服务器可以共同协作起来,共同构建分布式应用
java中实现一个序列化与反序列化
三个步骤
- 实现Serializable接口
- 使用ObjectInputStream读
- 使用ObjectOutputStream 写
对应代码例子
public class Person implements Serializable{
private static final long serialVersionUID = 385470237187218240L;
private String name;
private int 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class SerializeDemo {
public static void main(String[] args) throws Exception {
// 序列化
serializePerson();
// 反序列化
deSerializePerson();
}
private static void serializePerson() throws Exception {
Person person = new Person();
person.setName("张三");
person.setAge(12);
// System.out.println(person);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
oos.writeObject(person);
System.out.println("序列化完成,文件大小为:" + new File("person.txt").length());
}
private static void deSerializePerson() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"));
Person person = (Person) ois.readObject();
System.out.println(person);
}
}
java序列化的细节
serialVersionUID
=版本号
序列化以后,修改版本号,进行反序列化
Exception in thread "main" java.io.InvalidClassException: priv.dengjili.distributed_s1.serialize.bean.Person; local class incompatible: stream classdesc serialVersionUID = 385470237187218240, local class serialVersionUID = 85470237187218240
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at priv.dengjili.distributed_s1.serialize.demo.SerializeDemo2.deSerializePerson(SerializeDemo2.java:34)
at priv.dengjili.distributed_s1.serialize.demo.SerializeDemo2.main(SerializeDemo2.java:17)
ps: 添加会删除字段,不修改版本后,则反序列正常
静态变量的序列化
序列化并不保存静态变量的状态,因为静态变量不属于对象本身的内容
Transient关键字
transient关键字表示指定属性不参与序列化,过滤的意思
父子类问题
如果父类没有实现序列化,而子类实现列序列化。
只会序列化子类
序列化的存储规则
对同一个对象进行多次写入,打印出的第一次存储结果和第二次存储结果,只多了5个字节的引用关系。
并不会导致文件累加,存引用
序列化实现深度克隆
java中的深拷贝与浅拷贝:https://blog.csdn.net/dengjili/article/details/85716058
class Book implements Serializable {
private static final long serialVersionUID = 8234484588726379017L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book [name=" + name + "]";
}
}
class Teacher implements Serializable {
private static final long serialVersionUID = -7471815149371769182L;
private int no;
private Book book;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
@Override
public String toString() {
return "Teacher [no=" + no + ", book=" + book + "]";
}
public static void main(String[] args) throws Exception {
// 序列化
Book book = new Book();
book.setName("语文");
Teacher teacher = new Teacher();
teacher.setNo(10001);
teacher.setBook(book);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(teacher);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
// 反序列化
ObjectInputStream ois = new ObjectInputStream(bais);
Teacher teacher2 = (Teacher) ois.readObject();
System.out.println(teacher == teacher2);
System.out.println("老师1:" + teacher.getNo() + ",学科:" + teacher.getBook().getName());
System.out.println("老师2:" + teacher2.getNo() + ",学科:" + teacher2.getBook().getName());
teacher.setNo(2222);
teacher.getBook().setName("数学");
System.out.println("老师1:" + teacher.getNo() + ",学科:" + teacher.getBook().getName());
System.out.println("老师2:" + teacher2.getNo() + ",学科:" + teacher2.getBook().getName());
}
}
测试结果
false
老师1:10001,学科:语文
老师2:10001,学科:语文
老师1:2222,学科:数学
老师2:10001,学科:语文
常用序列化框架
公共依赖
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baidu/jprotobuf -->
<dependency>
<groupId>com.baidu</groupId>
<artifactId>jprotobuf</artifactId>
<version>2.2.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.caucho/hessian -->
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.51</version>
</dependency>
bean
Person
public class Person {
private String name;
private int 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
Person2
public class Person2 {
@Protobuf(fieldType = FieldType.STRING, order = 1)
private String name;
@Protobuf(fieldType = FieldType.INT32, order = 2)
private int 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
Person3
public class Person3 implements Serializable{
private static final long serialVersionUID = 3237645377924591122L;
private String name;
private int 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
FastSon
public class FastSonSerialize {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setName("张三");
person.setAge(12);
String text = JSON.toJSONString(person);
System.out.println(text);
System.out.println(text.getBytes().length);
Person person2 = JSON.parseObject(text, Person.class);
System.out.println(person == person2);
System.out.println(person2);
}
}
JackSon
public class JackSonSerialize {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setName("张三");
person.setAge(12);
ObjectMapper mapper = new ObjectMapper();
byte[] bytes = mapper.writeValueAsBytes(person);
System.out.println(new String(bytes));
System.out.println(bytes.length);
Person person2 = mapper.readValue(bytes, Person.class);
System.out.println(person == person2);
System.out.println(person2);
}
}
protobuf
/**
* 对应github链接: https://github.com/jhunters/jprotobuf
*
* @author it
*/
public class JprotobufSerialize {
public static void main(String[] args) throws Exception {
Codec<Person2> simpleTypeCodec = ProtobufProxy.create(Person2.class);
Person2 person = new Person2();
person.setName("张三");
person.setAge(12);
try {
// 序列化
byte[] bb = simpleTypeCodec.encode(person);
System.out.println(bb.length);
// 反序列化
Person2 person2 = simpleTypeCodec.decode(bb);
System.out.println(person == person2);
System.out.println(person2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hessian
public class HessianSerialize {
public static void main(String[] args) throws Exception {
Person3 Person = new Person3();
Person.setName("张三");
Person.setAge(12);
ByteArrayOutputStream buffers = new ByteArrayOutputStream();
HessianOutput output = new HessianOutput(buffers);
output.writeObject(Person);
byte[] byteArray = buffers.toByteArray();
System.out.println(byteArray.length);
HessianInput input = new HessianInput(new ByteArrayInputStream(byteArray));
Person3 person2 = (Person3) input.readObject(Person3.class);
System.out.println(Person == person2);
System.out.println(person2);
}
}