java序列化
序列化:将对象写入到IO流中
反序列化:从IO流中恢复对象
意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:程序创建的每个JavaBean类都实现Serializeable接口。
实例(Person实现了Serializeable接口):
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"))) {
//将对象序列化到文件object.txt
Person person = new Person("xuxiao", 222);
oos.writeObject(person);
反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"))) {
Person person = (Person) ois.readObject();
System.out.println(person);
ps:反序列化生成对象不会调用构造方法。反序列的对象是由JVM自己生成的对象,不通过构造方法生成。
transient关键字
有些时候,我们有这样的需求,某些属性不需要序列化。使用transient关键字选择不需要序列化的字段。
public class Person implements Serializable {
//不需要序列化名字与年龄
private transient String name;
private transient int age;
private int height;
private transient boolean singlehood;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//省略get,set方法
}
public class TransientTest {
public static void main(String[] args) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
ObjectInputStream ios = new ObjectInputStream(new FileInputStream("person.txt"))) {
Person person = new Person("xuxiao", 222);
person.setHeight(180);
System.out.println(person);
oos.writeObject(person);
Person p1 = (Person)ios.readObject();
System.out.println(p1);
}
}
}
输出结果:
//Person{name='xuxiao', age=222', singlehood=true', height=180cm}
//Person{name='null', age=0', singlehood=false', height=180cm}
使用transient修饰的属性,java序列化时,会忽略掉此字段,所以反序列化出的对象,被transient修饰的属性是默认值。对于引用类型,值是null;基本类型,值是0;boolean类型,值是false。
json
json是一种轻量级的数据交换格式。它基于 [ECMAScript] (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。360百科
JSON建构于两种结构:
“键/值”对的集合(A collection of name/value pairs)
在不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。 (结构)
而它的值,是有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。 (值=数组)
java中经常使用json格式来与前端交互,我通常使用fastjson来将javabean与json字符串之间相互转换。
Person person = new Person(20, "John", "Doe", new Date());
String jsonObject = JSON.toJSONString(person);
Person newPerson = JSON.parseObject(jsonObject, Person.class);
Json和Java实体的数据类型的对照(映射):
image.pngprotobuf
protobuf是google团队开发的用于高效存储和读取结构化数据的工具。什么是结构化数据呢,正如字面上表达的,就是带有一定结构的数据。比如电话簿上有很多记录数据,每条记录包含姓名、ID、邮件、电话等,这种结构重复出现。
xml、json也可以用来存储此类结构化数据,但是使用protobuf表示的数据能更加高效,并且将数据压缩得更小,大约是json格式的1/10,xml格式的1/20。
实际使用:
1.到http://code.google.com/p/protobuf/downloads/list ,选择其中的win版本下载,我选择的是protoc-2.4.1-win32.zip
2.下载一个protobuf-java-2.4.1.jar文件(注意,要与你刚才下的proto.exe版本相同)
3.用记事本编写一个.proto文件:
}如:我编写的是test.proto
package protobuf;
option java_package = "com.sq.protobuf";
option java_outer_classname = "FirstProtobuf";
message testBuf {
required int32 ID = 1;
required string Url = 2;
}
将其放在与刚解压的protoc.exe同级目录中。
在cmd中,到protoc-2.4.1-win32文件夹下,
执行
E:\protoc-2.4.1-win32> protoc.exe --java_out=./ test.proto
则可以找到的一个生成的FirstProtobuf.java文件。
5.将生成的FirstProtobuf.java放入工程。
image.png
6.编写测试类
package com.sq.protobuf;
import java.util.Arrays;
import com.google.protobuf.InvalidProtocolBufferException;
public class test2 {
public static void main(String[] args) {
//序列化
FirstProtobuf.testBuf.Builder builder = FirstProtobuf.testBuf.newBuilder();
builder.setID(117);
builder.setUrl("bangde");//同上
// testBuf
FirstProtobuf.testBuf info = builder.build();
byte[] result = info.toByteArray();
System.out.println("序列化结果:"+Arrays.toString(result));
//反序列化过程
try {
FirstProtobuf.testBuf testBuf = FirstProtobuf.testBuf.parseFrom(result);
System.out.println("反序列化过程:"+"\n"+testBuf);//打印反序列化的值
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
}
运行结果:
image.png
网友评论