IO_5_对象流+序列化

目录

1:对象的序列化

2:对象输入流和输出流

序列化实例eg

1:创建学生类,需要实现接口Serializable

2:创建Teacher类

3:序列化的使用

4:序列化和反序列化

1:serialVersionUID 常量

2:transient关键字--禁止序列化


1:对象的序列化

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。通过将对象序列化,可以方便的实现对象的传输及保存。

当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等,而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,实现进程间的对象传送,就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。

2:对象输入流和输出流

在Java中提供了ObjectlnputStream与ObjectOutputStream这两个类用于序列化对象的操作。使用对象输出流输出序列化对象的步骤,有时也称为序列化。使用对象输入流读入对象的过程,有时也称为反序列化。

 这两个类是用于存储和读取对象的输入输出流类,不难想象,只要把对象中的所有成员变量都存储起来,就等于保存了这个对象,之后从保存的对象之中再将对象读取进来就可以继续使用此对象。ObjectInputStream与ObjectOutputStream类,可以帮开发者完成保存和读取对象成员变量取值的过程,但要求读写或存储的对象必须实现了java.io.Serializable接口,但Serializable接口中没有定义任何方法,仅仅被用作一种标记,以被编译器作特殊处理。

如下范例所示:

import java.io.*;
public class Person implements Serializable{
	private String name;
	private int age;
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	public String toString(){
		return " 姓名:"+this.name+",年龄:"+this.age;
	}
}

第2行所中,类Person实现了Serializable接口,所以此类的对象可序列化。下面的范例使用ObjectOutputStream与ObjectInputStream将Person类的对象保存在文件之中

package cn.sz.gl.test05;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class Test {

	// 以下方法为序列化对象方法,将对象保存在文件之中
	public static void serialize(File f) throws Exception{
		OutputStream outputFile = new FileOutputStream(f);
		ObjectOutputStream cout = new ObjectOutputStream(outputFile)
		cout.writeObject(new Person("张三",25));
		cout.close();
	}

	// 以下方法为反序列化对象方法,从文件中读取已经保存的对象
	public static void deserialize(File f) throws Exception {
		InputStream inputFile = new FileInputStream(f);
		ObjectInputStream cin = new ObjectInputStream(inputFile);
		Person p = (Person) cin.readObject();
		System.out.println(p);
	}

	public static void main(String args[]) {
		File f = new File("SerializedPerson");
		serialize(f);
		deserialize(f);
	}
}

序列化实例eg

1:创建学生类,需要实现接口Serializable

        

package com.File_practise;

import java.io.Serializable;

public class Student implements Serializable {
   
    private static final long SerialServionID = 1l;
    private String name ;
    private String id ;


    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

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

2:创建Teacher类
package com.File_practise;

import java.io.Serializable;

public class Teacher implements Serializable {

    private String name ;
    private String card ;

    public Teacher() {
    }

    public Teacher(String name, String card) {
        this.name = name;
        this.card = card;
    }

    public String getName() {
        return name;
    }

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

    public String getCard() {
        return card;
    }

    public void setCard(String card) {
        this.card = card;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", card='" + card + '\'' +
                '}';
    }
}
3:序列化的使用
package com.File_practise;

import java.io.*;
import java.util.ArrayList;


public class Test1 {

    public static void main(String[] args) throws Exception {

//        创建4个不同的对象
        Teacher t1 = new Teacher("t1", "qqq");
        Teacher t2 = new Teacher("t2", "sss");
        Student s1 = new Student("cxy", "12345");
        Student s2 = new Student("lz", "34567");

        ArrayList<Student> students = new ArrayList<>();
        ArrayList<Teacher> teachers = new ArrayList<>();
        File file = new File("D:\\练习\\a.txt");
//        没有此文件就创建一个
        if (!file.exists()){
            file.createNewFile();
        }
//        将对象加入到数组
        students.add(s1);
        students.add(s2);
        teachers.add(t1);
        teachers.add(t2);
//        序列化
//        输出
        OutputStream outputStream = new FileOutputStream(file);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
//        将不同对象放在一起
        objectOutputStream.writeObject(students);
        objectOutputStream.writeObject(teachers);
//        关闭序列化
        objectOutputStream.close();

    }
}
4:序列化和反序列化
package com.File_practise;

import java.io.*;
import java.util.ArrayList;

public class Test2 {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Student s1 = new Student("cxy", "12345");
        Student s2 = new Student("lz", "12346");
        Student s3 = new Student("mb", "12347");
        Student s4 = new Student("hk", "12348");
        ArrayList<Student> students = new ArrayList<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);

        OutputStream fileOutputStream = new FileOutputStream("File/src/222.txt");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(students);
        objectOutputStream.close();


        FileInputStream fileInputStream = new FileInputStream("File/src/222.txt");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        ArrayList<Student> student = (ArrayList<Student>) objectInputStream.readObject();
        System.out.println(student);

    }
}

1:serialVersionUID 常量

在对象进行序列化或反序列化操作的时候,要考虑 JDK 版本的问题。如果序列化的 JDK 版本和反序列化的 JDK 版本不统一,则可能造成异常。因此在序列化操作中引入了一个serialVersionUID 的常量来验证版本的一致性。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体(类)的serialVersionUID 进行比较。如果相同就认为是一致的,可以进行反序列化,否则就会出现反序列化版本不一致的异常

Idea 配置自动生成序列号:

2:transient关键字--禁止序列化

如果不希望类中的属性被序列化,可以在声明属性之前加上transient关键字。如下所示,下面的代码修改自前面所用到的Person.java程序,在声明属性时,前面多加了一个transient关键字

private transient String name;

private transient int age;

注意:

序列化细节:

1) 被序列化的类的内部的所有属性,必须是可序列化的

2) static,transient修饰的属性,不可以被序列化

3:总结

1:对于序列化的概述:Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。通过将对象序列化,可以方便的实现对象的传输及保存。

2:关键字:序列化--Serializable ,禁止序列化--transient

4、建议采纳

如有建议或者错误请私信我进行修改,感谢!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值