java 序列化的方式

1、java原生的序列化

1.1、实现Serializable接口

序列化的时候的一个关键字:transient(临时的)。它声明的变量实行序列化操作的时候不会写入到序列化文件中去。

/**
 * Created by Lance on 2018/3/16.
 * 实现Serializable接口
 */
public class Person implements Serializable{

    private String name;
    private Integer age;
    //使用transient关键字修饰的变量不会被序列化
    private transient String address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Person() {
    }

    public Person(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}
/**
 * Created by Lance on 2018/3/16.
 * 把序列化的对象写到文件中去
 * 把文件中的对象读出来打印出来
 */
public class Main {

    public static void main(String[] args) {

        Person person = new Person("小红", 18, "三环");
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("D:\\work\\text4.txt"));
            outputStream.writeObject(person);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("D:\\work\\text4.txt"));
            Person person1 = (Person) inputStream.readObject();
            System.out.println(person1.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

1.2实现Externalizable接口:

一个类中我们只希望序列化一部分数据,其他数据都使用transient修饰的话显得有点麻烦,这时候我们使用externalizable接口,指定序列化的属性。

/**
 * Created by Lance on 2018/3/16.
 * 实现Externalizable接口
 */
public class Member implements Externalizable{

    private String name;
    private Integer age;
    private String address;

    public Member() {
    }

    public Member(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Member{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    //必须实现readExternal方法,控制读入什么属性
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        age = (Integer) in.readObject();
    }

    //必须实现writeExternal方法,控制写出什么属性
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeObject(age);
    }
}
/**
 * Created by Lance on 2018/3/16.
 * 把序列化的对象写到文件中去
 * 把文件中的对象读出来打印出来
 */
public class Main {

    public static void main(String[] args) {

        Member member = new Member("小红", 18, "三环");
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("D:\\work\\text4.txt"));
            outputStream.writeObject(member);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("D:\\work\\text4.txt"));
            Member member1 = (Member) inputStream.readObject();
            System.out.println(member1.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Externalizable 实例类的唯一特性是可以被写入序列化流中,该类负责保存和恢复实例内容。 若某个要完全控制某一对象及其超类型的流格式和内容,则它要实现 Externalizable 接口的 writeExternal 和 readExternal 方法。这些方法必须显式与超类型进行协调以保存其状态。这些方法将代替定制的 writeObject 和 readObject 方法实现。

writeExternal(ObjectOutput out) 
          该对象可实现 writeExternal 方法来保存其内容,它可以通过调用 DataOutput 的方法来保存其基本值,或调用 ObjectOutput 的 writeObject 方法来保存对象、字符串和数组。

readExternal(ObjectInput in) 
          对象实现 readExternal 方法来恢复其内容,它通过调用 DataInput 的方法来恢复其基础类型,调用 readObject 来恢复对象、字符串和数组。

2、Json序列化

Json序列化一般会使用jackson包,通过ObjectMapper类来进行一些操作,比如将对象转化为byte数组或者将json串转化为对象。现在的大多数公司都将json作为服务器端返回的数据格式。

3、FastJson序列化

fastjson 是由阿里巴巴开发的一个性能很好的Java 语言实现的 Json解析器和生成器。特点:速度快,测试表明fastjson具有极快的性能,超越任其他的java json parser。功能强大,完全支持java bean、集合、Map、日期、Enum,支持范型和自省。

4、ProtoBuff序列化

ProtocolBuffer是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化。适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

优点:跨语言;序列化后数据占用空间比JSON小,JSON有一定的格式,在数据量上还有可以压缩的空间。

缺点:它以二进制的方式存储,无法直接读取编辑,除非你有 .proto 定义,否则无法直接读出 Protobuffer的任何内容。

其与thrift的对比:两者语法类似,都支持版本向后兼容和向前兼容,thrift侧重点是构建跨语言的可伸缩的服务,支持的语言多,同时提供了全套RPC解决方案,可以很方便的直接构建服务,不需要做太多其他的工作。 Protobuffer主要是一种序列化机制,在数据序列化上进行性能比较,Protobuffer相对较好。


猜你喜欢

转载自blog.csdn.net/qq_28364999/article/details/79576159
今日推荐