一、Hessian序列化的前提
Hessian要实现序列化,前提是被序列化的类得实现Serializable接口。
二、Hessian序列化的实现
1.首先需要jar
2.代码实现
publicclassStudentimplementsSerializable{privateStringname;publicstaticStringhobby="eat";transientprivateStringaddress;}
写个测试类:
Student stu=newStudent();stu.setAddress("屋子科");stu.setName("ymz");ByteArrayOutputStream os=newByteArrayOutputStream();Hessian2Output output=newHessian2Output(os);output.writeObject(stu);output.close();Student.hobby="drink";ByteArrayInputStream bis=newByteArrayInputStream(os.toByteArray());Hessian2Input input=newHessian2Input(bis);Student student=(Student)input.readObject();System.out.println(student.getAddress());System.out.println(student.getName());System.out.println(stu.getHobby());
输出结果为:
nullymzdrink
读出来的静态属性的值是改变后的值,说明静态变量不参与序列化;transient修饰的属性的值为null,说明被transient关键字修饰的属性依然不参与序列化。
从结果可以得出以下结论:
静态属性不能被序列化;
transient关键字修饰的属性不能被序列化;
3.一个值得关注的坑
Stusdent类集成Teacher类,Teacher类中有跟Stusdent类型相同且属性名相同的字段name,接下来看代码:
publicclassStudentextendsTeacherimplementsSerializable{privateStringname;publicstaticStringhobby="eat";transientprivateStringaddress;}
publicclassTeacher{privateString name;}
测试类:
Student stu=newStudent();stu.setAddress("屋子科");stu.setName("ymz");ByteArrayOutputStream os=newByteArrayOutputStream();Hessian2Output output=newHessian2Output(os);output.writeObject(stu);output.close();ByteArrayInputStream bis=newByteArrayInputStream(os.toByteArray());Hessian2Input input=newHessian2Input(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的调用方式中性能更好。
作者:yunmuzhou丶
链接:https://www.jianshu.com/p/6a36dd1fcca8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。