首页 > 编程语言 > 详细

JAVA 序列化

时间:2015-06-27 21:18:42      阅读:255      评论:0      收藏:0      [点我收藏+]

1、对象序列化

  我们平时使用JAVA对象的时候,所有的操作都是在内存中进行的,即对象的生存周期不会比它所依赖的JVM更长。有时候我们又需要即使JVM已经停止,但是有能够在JVM停止后仍然能够获得之前的那些对象,即将这些对象持久化,JAVA对象序列化就能够帮助我们实现这个功能。

  JAVA对象序列化能够将对象保存为一组字节,并能够把这些字节在未来还原成对象。这些字节中保存的是对象的状态,即对象的成员变量,这就意味着类的静态对象不会被序列化。

  当进行网络传输的时候,RMI,也可以通过序列化传递对象。对于不同语言的平台一般通过XML进行通信。

  下面用一个简单示例来了解下对象序列化:

  在Java中只要一个类实现了Serializable接口就可以序列化。在这个示例中使用了使用了继承关系,枚举,成员变量是自定义类型。

  其中枚举默认继承了java.lang.Enum,这个类实现了Serializable接口

public enum Gender {
    MALE,FEMALE
}

  Java要求实现序列化的类的所有成员变量都是可序列化的,即成员变量必须实现Serializable接口

  其中People 是主要的测试类,它继承了Human,成员变量中有一个是Race类,都重写了toString()方法,方便打印。

  对于序列化的继承关系,稍后再论。这里只要知道,需要序列化的类,其成员变量必须可以序列化,其所有子类都自动实现序列化

public class Race implements Serializable{
    private static final long serialVersionUID = 1L;
    String nation;
    String race;
    public Race(String nation, String race) {
        super();
        this.nation = nation;
        this.race = race;
    }
    public Race() {
        super();
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "[nation " +nation+ " | race "+race+"]";
    }
}

public class Human implements Serializable{
    float tall;
    int age;
    public Human(float tall, int age) {
        super();
        this.tall = tall;
        this.age = age;
    }
    public Human() {
        super();
    }
    public String toString()
    {
        return "[ tall "+tall+" | age "+age+"]";
    }
}

public class People extends Human{
    private static final long serialVersionUID = 1L;
    
    String name;
    Race race;
    Gender gender;
    public People(float tall, int age, String name, Race race, Gender gender) {
        super(tall, age);
        this.name = name;
        this.race = race;
        this.gender = gender;
    }
    public People() {
        super();
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString()+"[ name "+name+" | gender "+gender+"]"+race;
    }
}

 这个是测试类。

public class Main {
    public static void main(String[] args) throws Exception
    {
        Race race=new Race("中国", "汉族");
        People people=new People(1.7f, 25, "赵钱孙", race, Gender.MALE);
        File file=new File("temp");
        //将对象持久化到文件中
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(people);
        oos.close();
        
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        Object object=ois.readObject();//没有强制类型转换,需要的话加上
        ois.close();
        
        System.out.println(object);
        
        People people2=new People(1.8f, 26, "李王陈", race, Gender.MALE);
        //将字节存储到字节数组中
        ByteArrayOutputStream bos =new ByteArrayOutputStream();
        ObjectOutputStream oos2=new ObjectOutputStream(bos);
        oos2.writeObject(people2);
        oos2.close();
        
        ObjectInputStream ois2=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        Object object2=ois2.readObject();
        ois2.close();
        
        System.out.println(object2);
    }
}

 

输出

[ tall 1.7 | age 25][ name 赵钱孙 | gender MALE][nation 中国 | race 汉族]
[ tall 1.8 | age 26][ name 李王陈 | gender MALE][nation 中国 | race 汉族]

 假如Race没有实现Serializable接口,会抛出 java.io.NotSerializableException: Race异常

 

2、可序列化的范围

为什么一个类实现了Serializable接口,它就可以被序列化呢?在上节的示例中,使用ObjectOutputStream来持久化对象,在该类中有如下代码:

private void writeObject0(Object obj, boolean unshared) throws IOException {  
      ...
    if (obj instanceof String) {  
        writeString((String) obj, unshared);  
    } else if (cl.isArray()) {  
        writeArray(obj, desc, unshared);  
    } else if (obj instanceof Enum) {  
        writeEnum((Enum) obj, desc, unshared);  
    } else if (obj instanceof Serializable) {  
        writeOrdinaryObject(obj, desc, unshared);  
    } else {  
        if (extendedDebugInfo) {  
            throw new NotSerializableException(cl.getName() + "\n" 
                    + debugInfoStack.toString());  
        } else {  
            throw new NotSerializableException(cl.getName());  
        }  
    }  
    ...  
} 

从上述代码可知,如果被写对象的类型是String,或数组,或Enum,或Serializable,还有基本类型,那么就可以对该对象进行序列化,否则将抛出NotSerializableException。

JAVA 序列化

原文:http://www.cnblogs.com/maydow/p/4604656.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!