对象流之序列化与反序列化

1.对象流–序列化和反序列化(serialization & deserialization)

  • 用于存储和读取基本数据类型数据或对象的处理流。
  • 以把Java中的对象写入到数据源中(序列化),也能把对象从数据源中还原回来(反序列化)。
  • ObjectOutputStream 类 : 把内存中的Java对象转换成平台无关的二进制数据,从而允许把这种二进制数据持久地保存在磁盘上,或通过网络将这种二进制数据传输到另一个网络节点。----》序列化
  • ObjectInputStream类 : 当其它程序获取了这种二进制数据,就可以恢复成原来的Java对象。----》反序列化

字符串的序列化和反序列化

// 字符串序列化操作 ObjectOutputStream
public static void strSerialization() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\Demo3.txt")));
        //将内存中的字符串写出到文件中:序列化操作,将“你好”--》二进制文件 存储到文件中
        oos.writeObject("你好");
        //关闭流:
        oos.close();
    }
//  字符串反序列化操作 ObjectIutputStream 
public static void strDeserialization() throws IOException, ClassNotFoundException {
        //将文件中保存的字符串 读入到 内存:
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\Demo3.txt")));
        //读取:反序列化。
        String s = (String)(ois.readObject());
        System.out.println(s); //输出“你好”
        //关闭流:
        ois.close();
    }

对于基本数据类型和Java中的引用类型,一般都实现了Serializable 接口,这是一个标识接口,只有实现该接口的类才能够进行序列化和反序列化操作。那么对于自定义的类怎么实现序列化和反序列化呢?

  • 查看Serializable 接口,接口内部,什么都没有,这种接口叫 标识接口。起到标识作用,只要实现这个接口的类的对象才能序列化,否则不可以
public interface Serializable {
}

2.自定义对象的序列化和反序列化

  • 自定义类实现Serializable 接口
  • 设置静态成员变量:serialVersionUID
    凡是实现Serializable接口(标识接口)的类都有一个表示序列化版本标识符的静态常量:
    private static final long serialVersionUID;
    ➢serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序加化时是否兼容。
    ➢如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
    ➢简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
  • 细节
    • 序列化类中的所有的属性都必须是可以序列化的
    • static和transient 修饰的属性不可以被序列化
/**
 * 如果对象需要序列化就必须实现Serializable接口
 * Serializable 是一个标识接口,只有对象实现了才能进行序列化和反序列化。
 *
 * 细节:
 * 1.序列化类中的所有的属性都必须是可以序列化的
 * 2.static transient 修饰的属性不可以被序列化
 *      需要保护的密码之类的属性可以采用transient 来修饰,防止别人采用反序列化方式来获取用户密码信息。
 */
public class Student implements Serializable {

    //序列化版本标识符的静态常量:用来表明类的不同版本间的兼容性。
    private static final long serialVersionUID = 8027651838638826533L;

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

    public Student(){}

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值