码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础教程——序列化

时间:2019-07-13 09:19:25      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:恢复   out   lse   absolute   otf   序列化   code   关键字   ansi   

序列化

序列化:Serialize,将Java对象写入IO流(可以保存在数据库,文件等)
反序列化:Deserialize,从IO流中读取并恢复Java对象。

这么理解:序列化就是把对象封印起来,反序列化就是解封。

对象中包含的不仅仅是字符,更多的是非字符,因此需要使用字节流。

所有能在网上传输的对象的类都应该是可序列化的,否则程序就会出现异常。

技术图片

实现Serializable接口

这个接口里面什么都没有,是一个标记接口,表明一个对象是可以序列化的。

public interface Serializable {
}

transient:瞬态关键字
|--transient变量---不参与序列化(有些变量可能属于敏感信息,如银行账户密码等)

transient:短暂的。

import java.io.*;
public class 序列化1 {
    public static void main(String[] args) throws Exception {
        int r_w = 3;
        if (r_w == 1) {
            on序列化();
        } else if (r_w == 2) {
            on反序列化();
        } else {
            on序列化();
            on反序列化();
        }
    }
    private static void on序列化() throws Exception {
        Dog _d = new Dog("狗", "金毛");
        File f = new File("myObj.txt");
        System.out.println("序列化:" + f.getAbsolutePath());
        FileOutputStream fos = new FileOutputStream(f);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(_d);
        oos.close();
        fos.close();
    }
    private static void on反序列化() throws Exception {
        // 前提:1.类必须可序列化,2.必须有对应的类文件
        File f = new File("myObj.txt");
        FileInputStream fis = new FileInputStream(f);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Dog d = (Dog) ois.readObject();
        System.out.println("反序列化:" + d + ": name = " + d.name);
        ois.close();
        fis.close();
    }
}
class Dog implements Serializable {
    private static final long serialVersionUID = 1L;
    public Dog(String name, String type) {
        super();
        this.name = name;
        this.type = type;
    }
    String name;
    transient String type;
    @Override
    public String toString() {
        System.out.println("type:没参与序列化");
        return "【狗狗:name = " + name + ", type = " + type + "】";
    }
}

运行结果:

序列化:C:\Users\Administrator\git\Ah01JspJavaHtml\myObj.txt
type:没参与序列化
反序列化:【狗狗:name = 狗, type = null】: name = 狗

序列号: serialVersionUID
|--修改类的定义,可能生成新的序列号
|--|--改构造器:变
|--|--改字段:变(包括transient字段)
|--|--改方法体里的实现,不变;

序列化和反序列化时的序列号如果不同,会抛出异常java.io.InvalidClassException
可以显示声明一个固定的序列号。如:

private static final long serialVersionUID = 1L;

*另一种序列化方法:实现Externalizable接口

Externalizable接口可以替代Serializable接口。

需要手提供一个无参构造方法,否则在反序列化的时候会抛出异常

java.io.InvalidClassException: ……; no valid constructor

同时还需要定义两个方法(writeExternal()和readExternal())来控制要序列化的字段。

下列示例,只有Dog类的实现和上例不一样,其余代码可以一样。

package ah.externalizable;
import java.io.*;
public class 序列化2 {
    public static void main(String[] args) throws Exception {
        on序列化();
        on反序列化();
    }
    private static void on序列化() throws Exception {
        Dog _d = new Dog("狗", "金毛");
        File f = new File("myObj.txt");
        System.out.println(f.getAbsolutePath());
        FileOutputStream fos = new FileOutputStream(f);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(_d);
        oos.close();
        fos.close();
    }
    private static void on反序列化() throws Exception {
        File f = new File("myObj.txt");
        FileInputStream fis = new FileInputStream(f);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Dog d = (Dog) ois.readObject();
        System.out.println(d + ": name = " + d.name);
        ois.close();
        fis.close();
    }
}
class Dog implements Externalizable {
    public Dog() {
        // 不写空构造,读不出来(可以写)
    }
    public Dog(String name, String type) {
        super();
        this.name = name;
        this.type = type;
    }
    String name;
    String type;
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        // 不写的Field就不序列化
        out.writeUTF(name);
        out.writeUTF(type);
    }
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        // 读取顺序务必和写入顺序相同
        name = in.readUTF();
        type = in.readUTF();
    }
    @Override
    public String toString() {
        return "【狗狗:" + name + ", 是一只" + type + "】";
    }
}

Java基础教程——序列化

标签:恢复   out   lse   absolute   otf   序列化   code   关键字   ansi   

原文地址:https://www.cnblogs.com/tigerlion/p/11179232.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!