2021-03-01

一、Hessian序列化的前提

Hessian要实现序列化,前提是被序列化的类得实现Serializable接口。

二、Hessian序列化的实现

1.首先需要jar

Hessian.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

来源:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(2021-03-01)