java基础---->Serializable的使用

  本次讲解中我们建立一个Java的项目去体会一下序列化Serializable的使用,序列化的原理以及序列化的自定义请参见我的另外一篇博客(java高级---->Serializable序列化的源码分析

目录导航

  1. Serializable序列化的简要说明
  2. Serializable序列化的代码实例
  3. Externalizable序列化的代码实例
  4. 友情链接

Serializable序列化的简要说明

一、 持久化的简单介绍:

  “持久化”意味着对象的“生存时间”并不取决于程序是否正在执行——它存在或“生存”于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序再次调用时重新恢复那个对象,就能圆满实现一种“持久”效果。

二、 语言里增加了对象序列化的概念后,可提供对两种主要特性的支持:

  • 远程方法调用(RMI)使本来存在于其他机器的对象可以表现出好象就在本地机器上的行为。将消息发给远程对象时,需要通过对象序列化来传输参数和返回值。
  • 使用一个Java Bean 时,它的状态信息通常在设计期间配置好。程序启动以后,这种状态信息必须保存下来,以便程序启动以后恢复;具体工作由对象序列化完成。

三、 Serializable的一些说明:

  • 对象的序列化处理非常简单,只需对象实现了Serializable 接口即可(该接口仅是一个标记,没有方法)
  • 序列化的对象包括基本数据类型,所有集合类以及其他许多东西,还有Class 对象
  • 对象序列化不仅保存了对象的“全景图”,而且能追踪对象内包含的所有句柄并保存那些对象;接着又能对每个对象内包含的句柄进行追踪
  • 使用transient关键字修饰的的变量,在序列化对象的过程中,该属性不会被序列化。

四、 序列化的步骤:

  • 首先要创建某些OutputStream对象:OutputStream outputStream = new FileOutputStream("output.txt")
  • 将其封装到ObjectOutputStream对象内:ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
  • 此后只需调用writeObject()即可完成对象的序列化,并将其发送给OutputStream:objectOutputStream.writeObject(Object);
  • 最后不要忘记关闭资源:objectOutputStream.close(), outputStream .close();

五、 反序列化的步骤:

  • 首先要创建某些OutputStream对象:InputStream inputStream= new FileInputStream("output.txt")
  • 将其封装到ObjectInputStream对象内:ObjectInputStream objectInputStream= new ObjectInputStream(inputStream);
  • 此后只需调用writeObject()即可完成对象的反序列化:objectInputStream.readObject();
  • 最后不要忘记关闭资源:objectInputStream.close(),inputStream.close();

Serializable序列化的代码实例

项目结构如下,源代码下载见huhx友情链接:

一、 首先我们建立一个Man类,实现了Serializable接口,用于Person类的测试:

package com.huhx.model;
import java.io.Serializable;

public class Man implements Serializable {
    private static final long serialVersionUID = 1L;

    private String username;
    private String password;

    public Man(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;
    }
}

二、 我们再建立一个Person类,用于序列化:

package com.huhx.model;
import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private Man man;
    private String username;
    private transient int age;

    public Person() {
        System.out.println("person constru");
    }

    public Person(Man man, String username, int age) {
        this.man = man;
        this.username = username;
        this.age = age;
    }

    public Man getMan() {
        return man;
    }
    public void setMan(Man man) {
        this.man = man;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

三、 编写一个包含main方法的测试类:MainTest,它的writeSerializableObject用于序列化对象:

// Serializable:把对象序列化
public static void writeSerializableObject() {
    try {
        Man man = new Man("huhx", "123456");
        Person person = new Person(man, "刘力", 21);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
        objectOutputStream.writeObject("string");
        objectOutputStream.writeObject(person);
        objectOutputStream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

四、  测试类MainTest,它的readSerializableObject用于反序列化对象:

// Serializable:反序列化对象
public static void readSerializableObject() {
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("output.txt"));
        String string = (String) objectInputStream.readObject();
        Person person = (Person) objectInputStream.readObject();
        objectInputStream.close();
        System.out.println(string + ", age: " + person.getAge() + ", man username: " + person.getMan().getUsername());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

五、 在Main方法添加以上两个方法的运行,结果如下:

   

  • 在Person类中包含Man的引用,当Person被序列化的时候,从结果可以知道Man也被序列化了
  • writeObject方法可以传入String,是因为String首先是一个类,其次它也是实现了Serializable接口的
  • Person类中的age字段是transient,从打印结果可以看到,序列化Person person = new Person(man, "刘力", 21)对象时,age没有进行序列化。如果transient修饰的Object类型的,那么打印的结果将会是null

Externalizable序列化的代码实例

首先我们看一下Externalizable的定义:继承了Serializable接口

public interface Externalizable extends java.io.Serializable

一、 同样的我们先创建一个实现了Externalizable的User类:重写里面两个方法readExternal和writeExternal

package com.huhx.model;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class User implements Externalizable {
    private String user;

    public String getUser() {
        return user;
    }

    public int getAge() {
        return age;
    }

    private int age;

    public User() {
        System.out.println("user constructor.");
    }

    public User(String user, int age) {
        System.out.println("user constructor two.");
        this.user = user;
        this.age = age;
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        System.out.println("read external.");
        user = (String) in.readObject();
        age = in.readInt();
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        System.out.println("write external.");
        out.writeObject(user);
        out.writeInt(age);
    }
}

二、  在MainTest中加入方法writeExternalizableObject,用于序列化对象User

// Externalizable的序列化对象
public static void writeExternalizableObject() {
    User user = new User("huhx", 22);
    try {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("Externalizable.txt"));
        objectOutputStream.writeObject(user);
        objectOutputStream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

三、 在MainTest中加入方法writeExternalizableObject,用于反序列化对象User

// Externalizable的反序列化对象
public static void readExternalizableObject() {
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("Externalizable.txt"));
        User user = (User) objectInputStream.readObject();
        objectInputStream.close();
        System.out.println("name: " + user.getUser() + ", age: " + user.getAge());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

四、 在Main方法添加以上两个方法的运行,结果如下:

  

  • 首先User user = new User("huhx", 22);执行了User的含参构造函数
  • 当执行到writeObject(user);方法时,由于User实现了Externalizable接口,所以它的writeExternal会执行,
  • 在User中的readExternal方法中调用了ObjectInput的readObject方法,在这个方法中通过反射机制创建User的实例,调用了User的无参构造函数。
  • 然后在readObject方法执行的时候,同样会先执行User类的readExternal方法。这个会在后续源代码分析时讲到

友情链接

时间: 2024-10-07 13:48:49

java基础---->Serializable的使用的相关文章

java高级---->Serializable的过程分析

本次讲解中我们在上次的基础上,深入的了解一下序列化的流程以及其中的原理.关于序列化的一些知识与使用,请参见我的另一篇博客:java基础---->Serializable的使用.好了,我们进行以下分析的讲解. 目录导航 Java序列化的原理分析 自定义Serializable的使用 友情链接 Java序列化的原理分析 java基础---->Serializable的使用的代码的演示,我们可以知道: 调用writeObject方法序列化一个对象,是将其写入磁盘,以后在程序再次调用readObjec

Java基础:序列化(Serializable)与反序列化

在学习IO中的ObjectOutputStream和ObjectInputStream时,会涉及到序列化和反序列化的应用,那么它们是什么? 一.概念 序列化:把对象转换为字节序列的过程,叫做对象的序列化. 反序列化:把字节序列恢复为对象的过程,叫做对象的反序列化. 二.作用 主要有两种用途: 1.把对象的字节序列永久保存在硬盘中,也就是把内存中的数据(对象)持久化处理. 2.可以在网络上传输对象的字符序列,对象不再局限于本地使用. 无论那种用途,实际上都是为了保存在内存中的各种对象的状态(也就是

java 基础(二)

java 基础(二)java 基础(二) 2016-2-1 by Damon 61. 编写多线程程序有几种实现方式 Java 5以前实现多线程有两种实现方法:一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活. 补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的

java基础篇---I/O技术(三)

接上一篇java基础篇---I/O技术(二) Java对象的序列化和反序列化 什么叫对象的序列化和反序列化 要想完成对象的输入或输出,还必须依靠对象输出流(ObjectOutputStream)和对象输入流(ObjectInputStream).使用对象输出流输出序列化对象的步骤,有时也成序列化,而使用对象输入流读入对象的过程,有时也称为反序列化 一个对象产生之后实际上是在内存中为其开辟了一个存储空间,方便存储信息. 对象序列化就是把一个对象变成二进制的数据流的一个方法,通过对象序列化可以反驳的

java基础问题总结

1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二是数据抽象. 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派生类可以从它的基类那里继承方法和实例变量,并

【Java基础】序列化与反序列化深入分析

一.前言 复习Java基础知识点的序列化与反序列化过程,整理了如下学习笔记. 二.为什么需要序列化与反序列化 程序运行时,只要需要,对象可以一直存在,并且我们可以随时访问对象的一些状态信息,如果程序终止,那么对象是肯定不会存在的,但是有时候,我们需要再程序终止时保存对象的状态信息,之后程序再次运行时可以重新恢复到之前的状态,如,玩家玩游戏退出时,需要保存玩家的状态信息(如等级.装备等等),之后玩家再此登入时,必须要恢复这些状态信息.我们可以通过数据库手段来达到这个保存状态的目的,在Java中,我

【DAY26】JAVA 基础回顾

基础回顾 ---------------- 1.跨平台 os JVM : sandbox 1995 2.基本数据类型 byte //1 -128 ~ 127 short //2 -32768 - 32767 int //4 long //8 float //4 doule //8 char //2 boolean //1 3.引用类型 [] class interface 4.运算符 && //短路 || //短路 & // | // ^ //抑或,相同0,不同为1 >>

No_16_0324 Java基础学习第二十三天

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.03.24 lutianfei none 登录注册IO版 如下代码仅为UserDaoImpl类文件,其他原码参考day22_login_regist工程 public class UserDaoImpl implements UserDao { // 为了保证文件一加载就创建 private static File file = new File("user.txt"); static { try { fil

JAVA基础英语单词表(下)

quantity                     / 'kw?ntiti /                    量,数量 query                            / 'kwi?ri /                       查询 queue                           / kju: /                                队列 rate                          / reit /