Java:序列化

一、序列化

1.概述

  • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
  • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
  • 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
  • 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

2.使用方法

  • 对象序列化流: ObjectOutputStream

  • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象

  • 对象反序列化流: ObjectInputStream

    • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
  • 注意

    • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
    • Serializable是一个标记接口,实现该接口,不需要重写任何方法
  • 构造方法

    方法名 说明
    ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream
    ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream
  • 对象方法

    方法名 说明
    void writeObject(Object obj) 将指定的对象写入ObjectOutputStream
    Object readObject() 从ObjectInputStream读取一个对象
  • User类:serialVersionUID&transient的使用


import java.io.Serializable;

//如果想要这个类的对象能被序列化,那么这个类必须要实现一个接口.Serializable

//Serializable 接口的意义
//称之为是一个标记性接口,里面没有任何的抽象方法
//只要一个类实现了这个Serializable接口,那么就表示这个类的对象可以被序列化.
public class User implements Serializable {
    //serialVersionUID 序列号
    //如果我们自己没有定义,那么虚拟机会根据类中的信息会自动的计算出一个序列号.
    //问题:如果我们修改了类中的信息.那么虚拟机会再次计算出一个序列号.

    //第一步:把User对象序列化到本地. --- -5824992206458892149
    //第二步:修改了javabean类. 导致 --- 类中的序列号 4900133124572371851
    //第三步:把文件中的对象读到内存. 本地中的序列号和类中的序列号不一致了.

    //解决?
    //不让虚拟机帮我们自动计算,我们自己手动给出.而且这个值不要变.

    private static final long serialVersionUID = 1L;

    private String username;
    private transient String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

  • 测试存取对象
static void method1() throws IOException, ClassNotFoundException {
    User user = new User("zhangsan","qwer");
    // 序列化
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
    oos.writeObject(user);
    oos.close();
    // 反序列化
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
    User o = (User) ois.readObject();
    System.out.println(o);
    ois.close();
}
  • 测试存取集合
static void test() throws IOException, ClassNotFoundException {
    //1.创建集合
    ArrayList<Student> arrayList = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        Student s = new Student("佟丽娅:"+ String.valueOf(i),30+i);
        arrayList.add(s);
    }

    //2.将集合对象序列化到文件中
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
    oos.writeObject(arrayList);
    oos.close();

    //3.将文件中的对象数据,读取到内存中
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
    Object obj = ois.readObject();
    ois.close();

    //取出集合对象
    ArrayList<Student> arrayList1 = (ArrayList<Student>)obj;
    for (Student s : arrayList) {
        System.out.println(s.getName() + "," + s.getAge());
    }
}

二、Properties集合

1、概述

  • 是一个Map体系的集合类
  • Properties可以保存到流中或从流中加载
  • 属性列表中的每个键及其对应的值都是一个字符串

2、常用方法

方法名 说明
Object setProperty(String key, String value) 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
String getProperty(String key) 使用此属性列表中指定的键搜索属性
Set<String> stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
public synchronized V put(K key, V value) 设置集合的键和值
public Set<K> keySet() 从该属性列表中返回一个不可修改的键集
static void test1(){
    // Properties<String,String> prop = new Properties<String,String>(); //错误
    Properties prop = new Properties();
    //设置集合的键和值,都是String类型
    for (int i = 0; i < 3; i++) {
        prop.setProperty("佟丽娅:"+ String.valueOf(i), String.valueOf("年龄" + i));
    }
    for (int i = 3; i < 6; i++) {
        prop.put("佟丽娅:"+ String.valueOf(i),30+i);
    }

    //使用此属性列表中指定的键搜索属性
    System.out.println(prop.getProperty("佟丽娅:3"));
    System.out.println(prop);

    //遍历集合
    Set<Object> keySet = prop.keySet();
    for (Object key : keySet) {
        Object value = prop.get(key);
        System.out.println(key + "," + value);
    }

    //从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
    Set<String> names = prop.stringPropertyNames();
    for (String key : names) {
        String value = prop.getProperty(key);
        System.out.println(key + "," + value);
    }
}

3Properties和IO流相结合

  • 和IO流结合的方法

    方法名 说明
    void load(Reader reader) 从输入字符流读取属性列表(键和元素对)
    void store(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流
private static void test2() throws IOException {
    Properties prop1 = new Properties();
    for (int i = 0; i < 3; i++) {
        prop1.setProperty("佟丽娅:"+ String.valueOf(i), String.valueOf("年龄" + i));
    }

    // 创建文件
    FileWriter fw = new FileWriter("fw.txt");
    // 保存Properties对象
    prop1.store(fw,null);
    fw.close();

    Properties prop2 = new Properties();
    // 读取文件
    FileReader fr = new FileReader("fw.txt");
    // 读取Properties对象
    prop2.load(fr);
    fr.close();

    System.out.println(prop2);
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容