java 序列化内容分析
来源:互联网 发布:js设置input可以编辑 编辑:程序博客网 时间:2024/04/30 10:22
网络通信,数据持久化的时候经常会涉及到对象序列化问题,如果对序列化的内容大小或者序列化的效率比较敏感,可以选择protobuf,hession等,如果不是特别在意这块,选择java默认的实现就可以了。java中通过调用ObjectOutputStream对象的writeObject()方法实现对象的序列化。来看段源码:
// remaining cases if (obj instanceof String) { writeString((String) obj, unshared); } else if (cl.isArray()) { writeArray(obj, desc, unshared); } else if (obj instanceof Enum) { writeEnum((Enum) obj, desc, unshared); } else if (obj instanceof Serializable) { writeOrdinaryObject(obj, desc, unshared); } else { if (extendedDebugInfo) { throw new NotSerializableException( cl.getName() + "\n" + debugInfoStack.toString()); } else { throw new NotSerializableException(cl.getName()); } }
ObjectOutputStream在写入对象的时候对四种不同的类型做了不同的处理,除了字符串,数组类型,枚举类型之外,其他的对象想要序列化必须实现Serializable这个标识接口。看到这里感觉好像基本数据类型(int,long之类)就不能写入,其实不是的。ObjectOutputStream在写入基本数据类型的时候会把它们转化成对象类写入,int的对象类就是Integer,而
Integer类的父类Number就是实现Serializable这个接口的。
经常看到网上说java中实现一个对象的序列化可以实现Serializable接口或者Externalizable接口,本质上Externalizable就是Serializable接口的一个子接口,但是实现Externalizable接口的类可以自定义写入需要通信或者持久化的字段信息。来看个例子:
public class ObjectTest {public static void main(String[] args) throws Exception {new ObjectTest().serialization();}public void serialization() throws Exception{URL url=ObjectTest.class.getResource("/config.properties");OutputStream output=new FileOutputStream(new File(url.getPath()));ObjectOutput objectOut=new ObjectOutputStream(output);objectOut.writeObject(new Object1());objectOut.close();output.close();URL url2=ObjectTest.class.getResource("/config2.properties");OutputStream output2=new FileOutputStream(new File(url2.getPath()));ObjectOutput objectOut2=new ObjectOutputStream(output2);objectOut2.writeObject(new Object2());objectOut2.close();objectOut2.close();}}
package net.flyingfat.serialization;import java.io.Serializable;public class Object1 implements Serializable {private static final long serialVersionUID = 1L;private String bac="abc";private int a=123;public String getBac() {return bac;}public void setBac(String bac) {this.bac = bac;}public int getA() {return a;}public void setA(int a) {this.a = a;}}
package net.flyingfat.serialization;import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;public class Object2 implements Externalizable {private static final long serialVersionUID = 1L;private String bac="123";private int a;public String getBac() {return bac;}public void setBac(String bac) {this.bac = bac;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.write(bac.getBytes("utf-8"));}@Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {in.readObject();}public int getA() {return a;}public void setA(int a) {this.a = a;}}
通过UE打开两个文件进行对比:
config.properties内容如下:
config2.properties内容如下:
2
截图内容太密,没法仔细标出每个字节是干嘛的,有兴趣的直接看源码吧,简单说明下:
1.两者开头都一样,写入类的定义(net.flyingfat.serialization.Object1/Object2),紧接着的8个字节就是 serialVersionUID(序列化id,它的作用应该都清楚)
2.后面具体对象的信息就一样了,实现Serializable接口的对象写入的是每个字段的类型,名字,和值,而实现Externalizable接口的对象写入的就是我们自定义的内容。
在来看另一个现象
public class Object1 extends Super {private static final long serialVersionUID = 1L;private String bac="abc";private int a=123;public String getBac() {return bac;}public void setBac(String bac) {this.bac = bac;}public int getA() {return a;}public void setA(int a) {this.a = a;}}class Super implements Serializable {private String s;public Super(String s) {super();this.s = s;}public Super() {}public String getS() {return s;}public void setS(String s) {this.s = s;}}
public class Object2 extends Super implements Serializable {private static final long serialVersionUID = 1L;private String bac="abc";private int a=123;public String getBac() {return bac;}public void setBac(String bac) {this.bac = bac;}public int getA() {return a;}public void setA(int a) {this.a = a;}}class Super {private String s;public Super(String s) {super();this.s = s;}public Super() {}public String getS() {return s;}public void setS(String s) {this.s = s;}}同时序列化这两个对象,可以看到内容不一样。
结论就是: 对象在序列化的时候,看该对象是直接还是间接实现Serializable接口,直接实现就只序列化当前对象本身的字段信息,如果是间接就会挨个往上找到父类,一并把父类的字段信息也序列化了。
- java 序列化内容分析
- Java序列化机制要序列化那些内容
- java 对象序列化要序列化那些内容
- Java序列化机制要序列化那些内容
- 深入分析java序列化
- Java 序列化深入分析
- java序列化的深入分析
- java的序列化机制原理分析
- 对 Java Serializable(序列化)分析
- 深入分析Java的序列化(Serialization)
- 深入分析Java的序列化(Serialization)
- java序列化保存对象的哪些内容
- java学习内容纲要分析
- java class文件内容分析
- Java序列化之Serializable(笔记,大部分内容来源于think in java 3th 中文版,bruceeckel)
- 深入分析Java的序列化与反序列化
- 深入分析Java的序列化与反序列化
- 深入分析Java的序列化与反序列化
- 利用php和mysql实现注册登录页面
- Java堆、栈和常量池以及相关String的讲解
- 转:非构造函数的继承
- 《Java小游戏实现》:贪吃蛇
- Python super继承详解
- java 序列化内容分析
- StateList Drawable文件
- hdu5294(最短路+网络流)
- coreseek(sphinx)的简单应用以及在LAMP中的注意事项
- centos6.6简单搭建git服务端
- 关于FileOutputStream
- [BOI2007]摩基亚Mokia (cdq分治)
- Java面向对象 ----多态
- android环境搭建和入门,php环境搭建和入门,java web环境搭建和入门