一、Hessian序列化的前提
Hessian要实现序列化,前提是被序列化的类得实现Serializable接口。
二、Hessian序列化的实现
1.首先需要jar
2.代码实现
public class Student implements Serializable {
private String name;
public static String hobby = "eat";
transient private String address;
}
写个测试类:
Student stu = new Student();
stu.setAddress("屋子科");
stu.setName("ymz");
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(os);
output.writeObject(stu);
output.close();
Student.hobby = "drink";
ByteArrayInputStream bis = new ByteArrayInputStream(os.toByteArray());
Hessian2Input input = new Hessian2Input(bis);
Student student = (Student) input.readObject();
System.out.println(student.getAddress());
System.out.println(student.getName());
System.out.println(stu.getHobby());
输出结果为:
null
ymz
drink
读出来的静态属性的值是改变后的值,说明静态变量不参与序列化;transient修饰的属性的值为null,说明被transient关键字修饰的属性依然不参与序列化。
从结果可以得出以下结论:
静态属性不能被序列化;
transient关键字修饰的属性不能被序列化;
3.一个值得关注的坑
Stusdent类集成Teacher类,Teacher类中有跟Stusdent类型相同且属性名相同的字段name,接下来看代码:
public class Student extends Teacher implements Serializable {
private String name;
public static String hobby = "eat";
transient private String address;
}
public class Teacher {
private String name;
}
测试类:
Student stu = new Student();
stu.setAddress("屋子科");
stu.setName("ymz");
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(os);
output.writeObject(stu);
output.close();
ByteArrayInputStream bis = new ByteArrayInputStream(os.toByteArray());
Hessian2Input input = new Hessian2Input(bis);
Student student = (Student) input.readObject();
System.out.println(student.getName());
输出结果为:
null
理论上输出的结果应该为“ymz”,但现在为null,原因如下:
hessian序列化的时候会取出对象的所有自定义属性,相同类型的属性是子类在前父类在后的顺序;
hessian在反序列化的时候,是将对象所有属性取出来,存放在一个map中 key = 属性名 value是反序列类,相同名字的会以子类为准进行反序列化;
相同名字的属性 在反序列化的是时候,由于子类在父类前面,子类的属性总是会被父类的覆盖,由于java多态属性,在上述例子中父类 student.name = null。
得出结论:
使用hessian序列化时,一定要注意子类和父类不能有同名字段
跟Serializable序列化的比较:
hessian序列化的效率更高,且序列化的数据更小,在基于RPC的调用方式中性能更好。