java序列化

来源:互联网 发布:淘宝美工一般要做什么 编辑:程序博客网 时间:2024/06/05 16:54

java序列化


  1. 为什么需要序列化?
    1. 当你创建对象时,只要你需要,它就会一直存在,但是在程序终止时,它将会不存在,有时我们需要保存对象在程序不运行时仍然保存内存中的各种对象的信息,等下次程序运行时把保存的对象信息再读出来,并且拥有的信息和上次运行时拥有的信息相同,
    2. 这个时候你可以通过信息写在磁盘或数据库中达到这个需求,但是在面向对象的世界中,将一个对象声明为持久性的,让java为我们处理所有的细节,这不是更好吗?
  2. 怎么实现序列化?
    1. java对象序列化将实现Serializable接口的对象转换为一个字节序列(流),并可以将这些字节序列完全恢复为原来的对象,这个过程可以在本机、甚至是网络进行,忽略不同操作系统的差异 。
    2. 虽然你可以用你自己的各种各样的方法来保存ObjectStates,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
  3. 什么情况下需要序列化
    1. 当你想把的内存中的对象保存到一个文件中或者数据库中时候;
    2. 当你想用套接字在网络上传送对象的时候;
    3. 当你想通过RMI(java远程方法调用)传输对象的时候;
  4. 在序列化时,有几点要注意的:
    1. 当一个对象被序列化时,只保存对象的非静态成员变量(包括声明为private的变量),不能保存任何的成员方法和静态的成员变量。
    2. 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被序列化。
    3. 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。
  5. 序列化的简单演示:
import java.io.*;import java.util.Arrays;import java.util.Random;/** * 实现序列化接口的狗 */class Dog implements Serializable {    private static final long serialVersionUID = -4670429746900191320L;    private int n;    public Dog(int n) {        this.n = n;    }    @Override    public String toString() {        return "Dog{" +                "n=" + n +                '}';    }}/** * 动物对象包含狗对象 * * @author yangyangxu */public class Animal implements Serializable {    private static final long serialVersionUID = 6495425009416846237L;    public static Random random = new Random();    /**     * 对象内部有对象,会把它包含的对象也也序列化,如果dog没有实现serializable接口,程序会出错     */    private Dog[] dogs = {            new Dog(random.nextInt(10)),            new Dog(random.nextInt(10)),            new Dog(random.nextInt(10))    };    private Animal next;    private char c;    /**     * name被序列化     */    private String name;    /**     * 如果你不需要对象的年龄被序列化,或者一个对象被还原以后,某子对象需要重新创建。从而不必将该对象序列化,可以使用transient标记该对象。     * 或者通过实行Enternalizable接口代替Seralizable接口,可以对序列化过程进行控制     */    transient String age;    /**     * 注意在对一个Serializable对象进行还原时,没有调用任何构造器,包括默认的,整个对象都是通过从InputStream中去的数据恢复的     */    public Animal() {        System.out.println("default constructor!");    }    public Animal(int i, char x) {        System.out.println("Animal consturctor:" + i);        this.c = x;        if (--i > 0) {            this.next = new Animal(i, (char) (x + 1));        }    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "Animal{" +                "dogs=" + Arrays.toString(dogs) +                ", next=" + next +                ", c=" + c +                ", name='" + name + '\'' +                ", age='" + age + '\'' +                '}';    }    public static void main(String[] args) throws IOException, ClassNotFoundException {        Animal animal = new Animal(2, 'b');        animal.setName("小红");        animal.setAge("18");        System.out.println("==========输出animal内存中信息=================");        System.out.println("animal = " + animal);        System.out.println("==========输出animal文件中信息=================");        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("animal.out"));        out.writeObject("动物\n");        out.writeObject(animal);        out.close();        ObjectInputStream input = new ObjectInputStream(new FileInputStream("animal.out"));        String s = (String) input.readObject();        Animal animal1 = (Animal) input.readObject();        System.out.println(s + "animal1 = " + animal1);        System.out.println("==========输出animal字节数组中信息=================");        ByteArrayOutputStream byteArray = new ByteArrayOutputStream();        ObjectOutputStream out2 = new ObjectOutputStream(byteArray);        out2.writeObject("动物\n");        out2.writeObject(animal);        out2.flush();        ObjectInputStream in2 = new ObjectInputStream(new ByteArrayInputStream(byteArray.toByteArray()));        s = (String) in2.readObject();        Animal animal2 = (Animal) in2.readObject();        System.out.println(s + "animal2 =" + animal2);        System.out.println();        System.out.println("由此可见:写入文件中和写入字节数组中,再次读出对象的信息没有变化!");    }}

程序输出结果:

Animal consturctor:2Animal consturctor:1==========输出animal内存中信息=================animal = Animal{dogs=[Dog{n=1}, Dog{n=9}, Dog{n=1}], next=Animal{dogs=[Dog{n=3}, Dog{n=1}, Dog{n=7}], next=null, c=c, name='null', age='null'}, c=b, name='小红', age='18'}==========输出animal文件中信息=================动物animal1 = Animal{dogs=[Dog{n=1}, Dog{n=9}, Dog{n=1}], next=Animal{dogs=[Dog{n=3}, Dog{n=1}, Dog{n=7}], next=null, c=c, name='null', age='null'}, c=b, name='小红', age='null'}==========输出animal字节数组中信息=================动物animal2 =Animal{dogs=[Dog{n=1}, Dog{n=9}, Dog{n=1}], next=Animal{dogs=[Dog{n=3}, Dog{n=1}, Dog{n=7}], next=null, c=c, name='null', age='null'}, c=b, name='小红', age='null'}由此可见:写入文件中和写入字节数组中,再次读出对象的信息没有变化!
  • 参考博客: JAVA序列化机制的深入研究
原创粉丝点击