序列化
2020年11月1日
8:54
引言
有些时候我们需要传输内存中的对象,例如通过网络传输封装好的数据实体。我们知道,数据传输最终都是二进制的形式,对象也是如此,将对象转成二进制数据就是序列化,反之,将二进制数据转成对象就是反序列化。
其中的核心问题在于,底层二进制码转为为对象,jvm如何知道二进制码哪里对应哪里,尤其是自定义类型,它如何找到类模板?这就要求类必须实现序列化的接口,Java中的基本类型都是实现了序列化接口的,而自定义的类则需要实现序列化和反序列化的操作。
Java中的序列化机制太重,包含大量信息,例如对应类模板。但这些信息对于分布式计算来负载过大,所以hadoop实现了自己的一套序列化api,这很好理解。比如IntWritable。hadoop的序列化特点就是,非常简单。
案例
下面是hadoop中的自定义序列化例子,非常好理解。
public class FlowBean implements Writable {
private long upFlow;
private long downFlow;
private long sumFlow;
public FlowBean() {
super();
}
public void set(long upFlow, long downFlow) {
this.upFlow = upFlow;
this.downFlow = downFlow;
this.sumFlow = this.upFlow + this.downFlow;
}
public long getUpFlow() {
return upFlow;
}
public void setUpFlow(long upFlow) {
this.upFlow = upFlow;
}
public long getDownFlow() {
return downFlow;
}
public void setDownFlow(long downFlow) {
this.downFlow = downFlow;
}
public long getSumFlow() {
return sumFlow;
}
public void setSumFlow(long sumFlow) {
this.sumFlow = sumFlow;
}
// 序列化
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeLong(upFlow);
dataOutput.writeLong(downFlow);
dataOutput.writeLong(sumFlow);
}
@Override
public void readFields(DataInput dataInput) throws IOException {
this.upFlow = dataInput.readLong();
this.downFlow = dataInput.readLong();
this.sumFlow = dataInput.readLong();
}
@Override
public String toString() {
return upFlow + "\t" + downFlow + "\t" + sumFlow;
}
}