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相对较好。