1. 序列化的目的是网络传输java对象(RMI)和对bean的序列化读写,实现轻量级的持久化
2. 序列化的实现是继承Serializable接口
3. 序列化后可以通过writeObject和readObject来实现对类的读写
4. 对于有些属性不需要序列化保存的,有两种方法:
a) 继承实现Externalizable接口,实现其方法,对指定的属性进行写入
b) 继承实现Serializable接口,使用关键字:transient来对不必要的属性进行排除
5. transient关键字只能和Serializable同时使用
6. 想序列化static值,需要手动去实现
看实例:
class Date implements Serializable{
privateint n;
publicDate(int n){
this.n= n;
}
publicString toString(){
returnInteger.toString(n);
}
}
/**
*java序列化,用于网络传输和对beans的序列化,比如保存配置信息
*cn.hibernate.test1.Worm.java
*@author ffr
*created at 2012-3-17
*/
public class Worm implements Serializable{
privatestatic Random rand = new Random(47);
privateDate[] d = {
newDate(rand.nextInt(10)),
newDate(rand.nextInt(10)),
newDate(rand.nextInt(10))
};
privateWorm next;
privatechar c;
publicWorm(int i, char x){
print("Wormconstructor: "+i);
c= x;
if(--i> 0){
next= new Worm(i, (char)(x+1));
}
}
publicWorm(){
print("Defaultconstructor");
}
publicString toString(){
StringBuilderresult = new StringBuilder(":");
result.append(c);
result.append("(");
for(Datedat : d){
result.append(dat);
}
result.append(")");
if(next!= null){
result.append(next);
}
returnresult.toString();
}
publicstatic void main(String[] args) throws ClassNotFoundException, IOException{
//初始化后输出
Wormw = new Worm(6,'a');
print("w= "+w);
//写入对象
ObjectOutputStreamout = new ObjectOutputStream(new FileOutputStream("worm.out"));
out.writeObject("Wormstorage\n");
out.writeObject(w);
out.close();
//读取对象
ObjectInputStreamin = new ObjectInputStream(new FileInputStream("worm.out"));
Strings = (String)in.readObject();
Wormw2 = (Worm)in.readObject();
//输出
print(s+"w2="+w2);
in.close();
//按字节写入
ByteArrayOutputStreambout = new ByteArrayOutputStream();
ObjectOutputStreamout2 = new ObjectOutputStream(bout);
out2.writeObject("Wormstorage\n");
out2.writeObject(w);
out2.close();
//按字节读取
ObjectInputStreamin2 = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray()));
s= (String)in2.readObject();
Wormw3 = (Worm)in2.readObject();
//输出
print(s+"w3= " + w3);
in2.close();
//最后结果都一样,足以说明序列化的作用,如果没有序列化,写入对象会报异常
}
privatestatic void print (String str){
System.out.println(str);
}
}/*Output
Worm constructor: 6
Worm constructor: 5
Worm constructor: 4
Worm constructor: 3
Worm constructor: 2
Worm constructor: 1
w =:a(853):b(119):c(802):d(788):e(199):f(881)
Worm storage
w2=:a(853):b(119):c(802):d(788):e(199):f(881)
Worm storage
w3 =:a(853):b(119):c(802):d(788):e(199):f(881)
*///:~
这样可以看出,对对象的读写,没有通过构造方法来实现,只是一个传输的过程
是怎么样读写和查找序列化类的,看代码:
public class Alien implements Serializable {
}
public class FreezeAlien {
public static void main(String[] args) throws Exception{
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("Y.file"));
Alien quellek = new Alien();
out.writeObject(quellek);
}
}
运行FreezeAlien会发现在项目根目录出现Y.file文件,这个就是产生的序列化文件,通过下面的方法恢复
public class ThwaAlien {
public static void main(String[] args) throws Exception{
ObjectInputStream in= new ObjectInputStream(new FileInputStream(new File(".","Y.file")));
Object mystery = in.readObject();
System.out.println(mystery.getClass());
}
}
//注意,对于上面红色字体部分,经过测试,这里的路径是从根目录查找开始的,所以“.”是正确的,至于java编程思想(第四版,P575)上的“..”,怎么测试也实现不了这种结果。
Transient关键字的具体实例:
/**
* 实现属性不序列化有两种方法:
* 1.继承实现Externalizable接口,实现其方法,对指定的属性进行写入
* 2.继承实现Serializable接口,使用关键字:transient来对不必要的属性进行排除
* cn.hibernate.test1.Logon.java
* @author ffr
* created at 2012-3-17
*/
public class Logon implements Serializable {
private java.util.Date date = new java.util.Date();
private String username;
private transient String password;
public Logon(String name, String pwd){
this.username = name;
this.password = pwd;
}
public String toString(){
return "logon info:\n username:"+username+"\ndate : "+date+"\n password:"+password;
}
public static void main(String[] args) throws Exception{
Logon a = new Logon("zhangsan", "123");
System.out.println("logon a =" + a);
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("logon.out"));
o.writeObject(a);
o.close();
TimeUnit.SECONDS.sleep(1);//延迟
//读取
ObjectInputStream in = new ObjectInputStream(new FileInputStream("logon.out"));
System.out.println("REcoveringobject ai " + new java.util.Date());
a = (Logon)in.readObject();
System.out.println("logon a =" + a);
}
}/**output
//不带关键字:transient
logon a = logon info:
username:zhangsan
date : Sat Mar 17 15:22:22 CST 2012
password :123
REcovering object ai Sat Mar 17 15:22:23 CST 2012
logon a = logon info:
username:zhangsan
date : Sat Mar 17 15:22:22 CST 2012
password :123
//带关键字:transient
logon a = logon info:
username:zhangsan
date : Sat Mar 17 15:22:58 CST 2012
password :123
REcovering object ai Sat Mar 17 15:22:59 CST 2012
logon a = logon info:
username:zhangsan
date : Sat Mar 17 15:22:58 CST 2012
password :null
*/