Java深入 - Java 序列化

Java 串行化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化到数据库、文件等系统里。

序列化的实现:将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

实现类的序列化,就需要implements Serializable这个接口类:

public class TestBo implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -2009384986168668986L;

    /**
     * 用户名
     */
    private String            userName;

    /**
     * 年龄
     */
    private String            age;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "TestBo [userName=" + userName + ", age=" + age + "]";
    }

}

我们可以看一个例子,将上面的TestBo类写入一个文件,并从这个文件中读取出来:

public class Test {

    public static void main(String[] args) {
        System.out.println("Java序列化测试类");

        TestBo testBo = new TestBo();
        testBo.setAge("100");
        testBo.setUserName("zhuli");
        try {
            //将序列化数据写入文件
            FileOutputStream out = new FileOutputStream("D:/test2.txt"); //文件输出流
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(out); //构造一个ObjectOutputStream
            objectOutputStream.writeObject(testBo); //写入对象
            System.out.println("序列化成功");
            
            out.close();
            objectOutputStream.close();
            
            
            //读取序列化
            FileInputStream in = new FileInputStream("D:/test2.txt"); //文件输出流
            ObjectInputStream objectInputStream = new ObjectInputStream(in); //构造一个ObjectInputStream
            TestBo testBo2 = (TestBo) objectInputStream.readObject(); //读取对象
            
            System.out.println(testBo2.toString());
            System.out.println("读取序列化成功");
            
            objectInputStream.close();
            in.close();
        } catch (Exception e) {
        }
    }

}

通过winhex 我们打开test2.txt文件,可以看到TestBo被序列化后的对象。

Java深入 - Java 序列化_第1张图片


如果需要在网络上传输,一般使用ByteArrayOutputStream,将对象序列化成byte[]数组,然后进行网络上的数据传输。可以看下下面的实现:

    public static void main(String[] args) {
        System.out.println("Java序列化测试类");

        TestBo testBo = new TestBo();
        testBo.setAge("100");
        testBo.setUserName("zhuli");
        try {
            //如果在网络上传输,一般使用ByteArrayOutputStream
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream byteOutObj = new ObjectOutputStream(byteOut);
            byteOutObj.writeObject(testBo);
            byte[] testBoByte = byteOut.toByteArray();
            System.out.println("序列化成功");
            
            //读取byteArray
            ByteArrayInputStream byteIn = new ByteArrayInputStream(testBoByte);
            ObjectInputStream  byteInObj = new ObjectInputStream(byteIn);
            TestBo testBo3= (TestBo) byteInObj.readObject();
            System.out.println(testBo3.toString());
            System.out.println("读取序列化成功");
            byteInObj.close();
            byteIn.close();
            byteOut.close();
            byteOutObj.close();

        } catch (Exception e) {
        }
    }

序列化需要注意一些事项:

1. 对象需要被序列化,那么必须实现Serializable接口。

2. 如果要被序列化的对象中,有域引用了一个其它的对象,那么这个对象也必须实现Serializable接口,否则无法序列化。如果引用的这个对象不需要被序列化,则需要添加关键字transient

3. 如果一个类本身没有实现Serializable接口,但是它的父类实现了Serializable接口,则可以被序列化

4. 如果一个类实现了Serializable接口,但是它的父类没有实现,这个类也是可以被序列化的,但是父类部分的域没有被序列化,所以要序列化的话父类也要实现Serializable接口。

5. 静态常量或者变量不会被序列化。(序列化了也没用)

你可能感兴趣的:(Java深入 - Java 序列化)