java 序列化和transient的用法

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

 */

 

 

你可能感兴趣的:(java,exception,String,Class,Constructor)