今天在看源码的是否发现BaseEntity实现了序列化接口。以前都是模仿别人在实体上实现序列化接口。为了更好的理解序列化的意义,总结java对象序列化。
java对象从内存中写入到磁盘时,经过如下步骤:
(1).声明一个ObjectOutputStream对象,构造ObjectOutputStream对象的时候,传递FileOutputStream对象参数。构造FileOutputStream对象的时候,传递文件或文件路径参数。
(2).构造对象,通过ObjectOutputStream的writeObject方法写入到流中。
import java.util.Date;
public abstract class BaseEntity {
private String id;
private Date createTime;
private Date modifyTime;
private Date deleteTime;
private String createUser;
private String modifyUser;
private String deleteUser;
private int deleteFlag = 2;
private boolean checked = false;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getModifyTime() {
return modifyTime;
}
public void setModifyTime(Date modifyTime) {
this.modifyTime = modifyTime;
}
public Date getDeleteTime() {
return deleteTime;
}
public void setDeleteTime(Date deleteTime) {
this.deleteTime = deleteTime;
}
public String getCreateUser() {
return createUser;
}
public void setCreateUser(String createUser) {
this.createUser = createUser;
}
public String getModifyUser() {
return modifyUser;
}
public void setModifyUser(String modifyUser) {
this.modifyUser = modifyUser;
}
public String getDeleteUser() {
return deleteUser;
}
public void setDeleteUser(String deleteUser) {
this.deleteUser = deleteUser;
}
public int getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(int deleteFlag) {
this.deleteFlag = deleteFlag;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
}
public class Person extends BaseEntity {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "name:"+this.getName()+
"age:"+this.getAge()+
"checked:"+this.isChecked()+
"createTime:"+this.getCreateTime();
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
//序列化
Person p1=new Person();
p1.setAge(1);
p1.setChecked(true);
p1.setCreateTime(new Date());
p1.setName("liming");
FileOutputStream fos=null;
ObjectOutputStream oos=null;
try {
fos=new FileOutputStream("person1.txt");
oos=new ObjectOutputStream(fos);
oos.writeObject(p1);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(oos!=null){
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
运行结果为:
java.io.NotSerializableException: net.chinaedu.projects.g3mini.Person
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at net.chinaedu.projects.g3mini.Test.main(Test.java:27)
从报错结果可以分析出ObjectOutputStream.writeObject方法报错。writeObject方法的源码:
/**
* Underlying writeObject/writeUnshared implementation.
*/
private void writeObject0(Object obj, boolean unshared)
throws IOException
{
boolean oldMode = bout.setBlockDataMode(false);
depth++;
try {
// handle previously written and non-replaceable objects
int h;
if ((obj = subs.lookup(obj)) == null) {
writeNull();
return;
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);
return;
} else if (obj instanceof ObjectStreamClass) {
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
}
// check for replacement object
Object orig = obj;
Class cl = obj.getClass();
ObjectStreamClass desc;
for (;;) {
// REMIND: skip this check for strings/arrays?
Class repCl;
desc = ObjectStreamClass.lookup(cl, true);
if (!desc.hasWriteReplaceMethod() ||
(obj = desc.invokeWriteReplace(obj)) == null ||
(repCl = obj.getClass()) == cl)
{
break;
}
cl = repCl;
}
if (enableReplace) {
Object rep = replaceObject(obj);
if (rep != obj && rep != null) {
cl = rep.getClass();
desc = ObjectStreamClass.lookup(cl, true);
}
obj = rep;
}
// if object replaced, run through original checks a second time
if (obj != orig) {
subs.assign(orig, obj);
if (obj == null) {
writeNull();
return;
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);
return;
} else if (obj instanceof ObjectStreamClass) {
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
}
}
// 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());
}
}
} finally {
depth--;
bout.setBlockDataMode(oldMode);
}
}
其中有一段代码是判断obj类型的,如下
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());
}
}
先判断obj对象是不是String,Array,Enum,以上都不是的时候,判断是不是对象是不是Serializable的实例。不是的话,写入方法内部会throw NotSerializableException。
读取反序列化文件:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ReadPerson1Test {
/**
* 读取序列化的内容
*/
public static void main(String[] args) {
FileInputStream fis=null;
ObjectInputStream ois=null;
try {
fis=new FileInputStream("F:/101edu/svn-work/svn-shiyanban/trunk/dev/src/cedu.g3mini/src/main/java/net/chinaedu/projects/g3mini/person1.txt");
ois=new ObjectInputStream(fis);
Person p=(Person) ois.readObject();
System.err.println(p.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}