java序列化之保存对象到文件中

 

java源码:
import java.io.*;

public class LoginUser {
 private String username;
 private String passwd;
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 public String getPasswd() {
  return passwd;
 }
 public void setPasswd(String passwd) {
  this.passwd = passwd;
 }
 
 public static void main(String[] args){  
  LoginUser loginUser = new LoginUser();  
  loginUser.setUsername("50");  
        loginUser.setPasswd("30");  
  
        try{  
            FileOutputStream fs = new FileOutputStream("foo.ser");  
            ObjectOutputStream os =  new ObjectOutputStream(fs);  
            os.writeObject(loginUser);  
            os.close();  
        }catch(Exception ex){  
            ex.printStackTrace();  
        }  
    }  

}

报错如下:

java.io.NotSerializableException: com.longshine.zwp.test.LoginUser
 at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
 at com.longshine.zwp.test.LoginUser.main(LoginUser.java:29)

 

类的定义改成如下:

public class LoginUser implements Serializable{

}

则可以保存下来内存中的java对象。

 

1、序列化是干什么的?
       简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

2、什么情况下需要序列化  
    a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
    b)当你想用套接字在网络上传送对象的时候;
    c)当你想通过RMI传输对象的时候;

3、当对一个对象实现序列化时,究竟发生了什么?
    在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如:
   

java 代码
  1. Foo  myFoo = new Foo();  
  2. myFoo .setWidth(37);  
  3. myFoo.setHeight(70);  

     
       当 通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它 从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对 象。

java 代码
  1. FileOutputStream fs = new FileOutputStream("foo.ser");  
  2. ObjectOutputStream os = new ObjectOutputStream(fs);  
  3. os.writeObject(myFoo);  


4、实现序列化(保存到一个文件)的步骤
      
a)Make a FileOutputStream                    b)Make a ObjectOutputStream           

java 代码
  1. FileOutputStream fs = new FileOutputStream("foo.ser");    

 

java 代码
  1. ObjectOutputStream os =  new ObjectOutputStream(fs);   

       c)write the object

java 代码
  1. os.writeObject(myObject1);  
  2. os.writeObject(myObject2);  
  3. os.writeObject(myObject3);  

    d) close the ObjectOutputStream

java 代码
  1. os.close();  



5、举例说明

6、相关注意事项
    a)序列化时,只对对象的状态进行保存,而不管对象的方法;
    b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
    c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
    d)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:
        1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
       2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分  配,而且,也是没有必要这样实现。

java 代码


import java.io.*;
public class LoginUser implements Serializable{
 /**
  *
  */
 private static final long serialVersionUID = -4382915422537471820L;
 private String username;
 private String passwd;
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 public String getPasswd() {
  return passwd;
 }
 public void setPasswd(String passwd) {
  this.passwd = passwd;
 }
 
 public static void save() {
  LoginUser loginUser = new LoginUser();
  loginUser.setUsername("50");
  loginUser.setPasswd("30");
  try {
   FileOutputStream fs = new FileOutputStream("loginuser.txt");
   ObjectOutputStream os = new ObjectOutputStream(fs);
   os.writeObject(loginUser);
   os.flush();
   os.close();
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }
 
 public static void read() {
  try {
   FileInputStream fs = new FileInputStream("loginuser.txt");//("foo.ser");
   ObjectInputStream ois = new ObjectInputStream(fs);
   LoginUser loginUser = (LoginUser) ois.readObject();
   System.out.println(loginUser.getUsername() + "----"
     + loginUser.getPasswd());
   ois.close();
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }
 
 public static void main(String[] args){  
       save();
       read();
    }  
}

 序列化、反序列化为XML文件,使用XStream来序列化,需要引入xstream-1.3.1.jar包的支持,
http://xstream.codehaus.org/download.html  处可以下载jar,然后引入到Eclipse中的build path中。
Serialize.java的代码如下:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import com.thoughtworks.xstream.*;

public class Serialize {
    public static void main(String[] args) {
        Serialize ser = new Serialize();
        ser.serializeToXml();
        ser.deSerializeFromXml();
    }
   
public void serializeToXml(){
        Person[] myPerson = new Person[2];
        myPerson[0] = new Person("Jay",24);
        myPerson[1] = new Person("Tom",23);
       
        XStream xstream = new XStream(); 
        try {
            FileOutputStream fos = new FileOutputStream("E:\\workspace\\2010_03\\src\\myPerson.xml");
             xstream.toXML(myPerson,fos);
             } catch (FileNotFoundException ex) {
             ex.printStackTrace();
             }      
        System.out.println(xstream.toXML(myPerson));
    }
    public void deSerializeFromXml(){
         XStream xs = new XStream();
         Person[] myPerson = null;

         try {
         FileInputStream fis = new FileInputStream("E:\\workspace\\2010_03\\src\\myPerson.xml");
         myPerson=(Person[])xs.fromXML(fis);
         if (myPerson != null)
         {
             int len = myPerson.length;
             for (int i=0;i<len;i++)
             {
                 System.out.println(myPerson[i].getName());
                 System.out.println(myPerson[i].getAge());
             }

         }
         } catch (FileNotFoundException ex) {
         ex.printStackTrace();
         }
    }
}
运行结果为(console输出),当然可以查看到myPerson.xml文件已经生成:
Inside Person's Constructor
Inside Person's Constructor
<Person-array>
  <Person>
    <name>Jay</name>
    <age>24</age>
  </Person>
  <Person>
    <name>Tom</name>
    <age>23</age>
  </Person>
</Person-array>
Jay
24
Tom
23

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值