java序列化定义
序列化
把Java对象转换为字节序列的过程称为对象的序列化。
反序列化
把字节序列恢复为Java对象的过程称为对象的反序列化。
用途
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
方法,参考上篇 java 将对象写入文件进行保存和读取
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。
可以认为Serializable接口统一了所有序列化行为。
上一篇提到HashMap是一个序列化的类,那么如何自己写个序列化的类
package com.javaer.examples.file;
import java.io.Serializable;
public class Car implements Serializable {
private String name;
private String color;
public Car(String name,String color){
this.name = name;
this.color = color;
}
public String toString(){
return ‘‘name:‘‘ + this.name + ‘‘ color:‘‘ + this.color;
}
}
上面的例子很简单,标准的类,实现Serializable接口即可
Car c = new Car(‘‘Volvo S80L‘‘,‘‘black‘‘);
try {
StoreFileObject.writeObject(‘‘/car‘‘, c);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
写一个Main函数,利用上一遍的 java 将对象写入文件进行保存和读取试一下。是不是可以存入文件了。
实现Externalizable接口
Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:
public void writeExternal(ObjectOutput out) throws IOException
public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException
前者负责序列化操作,后者负责反序列化操作。
在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常。
可序列化类的不同版本的序列化兼容性
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
private static final long serialVersionUID;
以上serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
首发于 http://java-er.com - http://java-er.com/blog/java-serializable/
序列化
把Java对象转换为字节序列的过程称为对象的序列化。
反序列化
把字节序列恢复为Java对象的过程称为对象的反序列化。
用途
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
方法,参考上篇 java 将对象写入文件进行保存和读取
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。
可以认为Serializable接口统一了所有序列化行为。
上一篇提到HashMap是一个序列化的类,那么如何自己写个序列化的类
package com.javaer.examples.file;
import java.io.Serializable;
public class Car implements Serializable {
private String name;
private String color;
public Car(String name,String color){
this.name = name;
this.color = color;
}
public String toString(){
return ‘‘name:‘‘ + this.name + ‘‘ color:‘‘ + this.color;
}
}
上面的例子很简单,标准的类,实现Serializable接口即可
Car c = new Car(‘‘Volvo S80L‘‘,‘‘black‘‘);
try {
StoreFileObject.writeObject(‘‘/car‘‘, c);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
写一个Main函数,利用上一遍的 java 将对象写入文件进行保存和读取试一下。是不是可以存入文件了。
实现Externalizable接口
Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:
public void writeExternal(ObjectOutput out) throws IOException
public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException
前者负责序列化操作,后者负责反序列化操作。
在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常。
可序列化类的不同版本的序列化兼容性
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
private static final long serialVersionUID;
以上serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
首发于 http://java-er.com - http://java-er.com/blog/java-serializable/