java中的IO整理(6)

对象的序列化

 

对象序列化就是把一个对象变为二进制数据流的一种方法。

 

一个类要想被序列化,就行必须实现java.io.Serializable接口。虽然这个接口中没有任何方法,就如同之前的cloneable接口一样。实现了这个接口之后,就表示这个类具有被序列化的能力。

 

先让我们实现一个具有序列化能力的类吧:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import  java.io.*;
/**
  * 实现具有序列化能力的类
  * */
public  class  SerializableDemo implements  Serializable{
     public  SerializableDemo(){
         
     }
     public  SerializableDemo(String name, int  age){
         this .name=name;
         this .age=age;
     }
     @Override
     public  String toString(){
         return  "姓名:" +name+ "  年龄:" +age;
     }
     private  String name;
     private  int  age;
}

 

这个类就具有实现序列化能力,

 

在继续将序列化之前,先将一下ObjectInputStreamObjectOutputStream这两个类

 

先给一个ObjectOutputStream的例子吧:

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import  java.io.Serializable;
import  java.io.File;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectOutputStream;
 
/**
  * 实现具有序列化能力的类
  * */
public  class  Person implements  Serializable{
     public  Person(){
 
     }
 
     public  Person(String name, int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:"  + name + "  年龄:"  + age;
     }
 
     private  String name;
     private  int  age;
}
/**
  * 示范ObjectOutputStream
  * */
public  class  ObjectOutputStreamDemo{
     public  static  void  main(String[] args) throws  IOException{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectOutputStream oos = new  ObjectOutputStream( new  FileOutputStream(
                 file));
         oos.writeObject( new  Person( "rollen" , 20 ));
         oos.close();
     }
}

 

 

【运行结果】:

 

当我们查看产生的hello.txt的时候,看到的是乱码,呵呵。因为是二进制文件。

 

虽然我们不能直接查看里面的内容,但是我们可以使用ObjectInputStream类查看:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.ObjectInputStream;
 
/**
  * ObjectInputStream示范
  * */
public  class  ObjectInputStreamDemo{
     public  static  void  main(String[] args) throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectInputStream input = new  ObjectInputStream( new  FileInputStream(
                 file));
         Object obj = input.readObject();
         input.close();
         System.out.println(obj);
     }
}

 

【运行结果】

 

姓名:rollen  年龄:20

 

 

 

到底序列化什么内容呢?

 

其实只有属性会被序列化。

 

Externalizable接口

 

Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。

 

当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。

 

现在我们来演示一下序列化和反序列话:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package  IO;
 
import  java.io.Externalizable;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectInput;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutput;
import  java.io.ObjectOutputStream;
 
/**
  * 序列化和反序列化的操作
  * */
public  class  ExternalizableDemo{
     public  static  void  main(String[] args) throws  Exception{
         ser(); // 序列化
         dser(); // 反序列话
     }
 
     public  static  void  ser() throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectOutputStream out = new  ObjectOutputStream( new  FileOutputStream(
                 file));
         out.writeObject( new  Person( "rollen" , 20 ));
         out.close();
     }
 
     public  static  void  dser() throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectInputStream input = new  ObjectInputStream( new  FileInputStream(
                 file));
         Object obj = input.readObject();
         input.close();
         System.out.println(obj);
     }
}
 
class  Person implements  Externalizable{
     public  Person(){
 
     }
 
     public  Person(String name, int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:"  + name + "  年龄:"  + age;
     }
 
     // 复写这个方法,根据需要可以保存的属性或者具体内容,在序列化的时候使用
     @Override
     public  void  writeExternal(ObjectOutput out) throws  IOException{
         out.writeObject( this .name);
         out.writeInt(age);
     }
 
     // 复写这个方法,根据需要读取内容 反序列话的时候需要
     @Override
     public  void  readExternal(ObjectInput in) throws  IOException,
             ClassNotFoundException{
         this .name = (String) in.readObject();
         this .age = in.readInt();
     }
 
     private  String name;
     private  int  age;
}

 

【运行结果】:

 

姓名:rollen  年龄:20

 

本例中,我们将全部的属性都保留了下来,

 

Serializable接口实现的操作其实是吧一个对象中的全部属性进行序列化,当然也可以使用我们上使用是Externalizable接口以实现部分属性的序列化,但是这样的操作比较麻烦,

 

当我们使用Serializable接口实现序列化操作的时候,如果一个对象的某一个属性不想被序列化保存下来,那么我们可以使用transient关键字进行说明:

 

下面举一个例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package  IO;
 
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;
import  java.io.Serializable;
 
/**
  * 序列化和反序列化的操作
  * */
public  class  serDemo{
     public  static  void  main(String[] args) throws  Exception{
         ser(); // 序列化
         dser(); // 反序列话
     }
 
     public  static  void  ser() throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectOutputStream out = new  ObjectOutputStream( new  FileOutputStream(
                 file));
         out.writeObject( new  Person1( "rollen" , 20 ));
         out.close();
     }
 
     public  static  void  dser() throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectInputStream input = new  ObjectInputStream( new  FileInputStream(
                 file));
         Object obj = input.readObject();
         input.close();
         System.out.println(obj);
     }
}
 
class  Person1 implements  Serializable{
     public  Person1(){
 
     }
 
     public  Person1(String name, int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:"  + name + "  年龄:"  + age;
     }
 
     // 注意这里
     private  transient  String name;
     private  int  age;
}

 

【运行结果】:

 

姓名:null  年龄:20

 

最后在给一个序列化一组对象的例子吧:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;
import  java.io.Serializable;
 
/**
  * 序列化一组对象
  * */
public  class  SerDemo1{
     public  static  void  main(String[] args) throws  Exception{
         Student[] stu = { new  Student( "hello" , 20 ), new  Student( "world" , 30 ),
                 new  Student( "rollen" , 40 ) };
         ser(stu);
         Object[] obj = dser();
         for ( int  i = 0 ; i < obj.length; ++i){
             Student s = (Student) obj[i];
             System.out.println(s);
         }
     }
 
     // 序列化
     public  static  void  ser(Object[] obj) throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectOutputStream out = new  ObjectOutputStream( new  FileOutputStream(
                 file));
         out.writeObject(obj);
         out.close();
     }
 
     // 反序列化
     public  static  Object[] dser() throws  Exception{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         ObjectInputStream input = new  ObjectInputStream( new  FileInputStream(
                 file));
         Object[] obj = (Object[]) input.readObject();
         input.close();
         return  obj;
     }
}
 
class  Student implements  Serializable{
     public  Student(){
 
     }
 
     public  Student(String name, int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:  "  + name + "  年龄:"  + age;
     }
 
     private  String name;
     private  int  age;
}

 

【运行结果】:

 

姓名:  hello  年龄:20

 

姓名:  world  年龄:30

 

姓名:  rollen  年龄:40

 

 

 

写在最后:本文章没有涉及java.nio,等我有时间,我自会补上的,欢迎大家关注我的博客,大家一起交流学习。

 

转自:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值