java序列化之Hessian

一、Hessian序列化的前提

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

二、Hessian序列化的实现
1.首先需要jar

Hessian.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,原因如下:

  1. hessian序列化的时候会取出对象的所有自定义属性,相同类型的属性是子类在前父类在后的顺序;
  2. hessian在反序列化的时候,是将对象所有属性取出来,存放在一个map中 key = 属性名 value是反序列类,相同名字的会以子类为准进行反序列化;
  3. 相同名字的属性 在反序列化的是时候,由于子类在父类前面,子类的属性总是会被父类的覆盖,由于java多态属性,在上述例子中父类 student.name = null。

得出结论:

使用hessian序列化时,一定要注意子类和父类不能有同名字段

跟Serializable序列化的比较:

hessian序列化的效率更高,且序列化的数据更小,在基于RPC的调用方式中性能更好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容