学习笔记之JavaSE(47)--IO流9

本文介绍Java中如何使用ObjectOutputStream和ObjectInputStream类实现对象的序列化和反序列化,包括注意事项如序列化接口、瞬时变量、静态变量等特性及其实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天学习的内容是ObjectOutputStream类和ObjectInputStream类


ObjectOutputStream类和ObjectInputStream类都是装饰器类,它们让字节流具备写入读取二进制对象的功能。其中写入对象也称为对象的序列化--使用ObjectOutputStream类的writeObject()方法;而读取对象称为对象的反序列化--使用ObjectInputStream类的readObject()方法。对象序列化与反序列化的知识点总结如下:

  • 只有实现Serializable接口的类的对象才能被序列化
  • 可序列化类的子类是自动可序列化的
  • 对象网的所有对象都会被序列化(比如对象中引用变量所指向的对象)
  • 被序列化的变量只有非瞬时变量和非静态变量
  • 瞬时变量由transient关键字修饰,瞬时变量不会被序列化,对象反序列化时该变量会被赋默认值
  • 静态变量也不会被序列化,而且值不会被改变(因为静态变量存储在方法区中,即使是网络传输,也会在类第一次加载时存储在方法区)
  • 读取对象的顺序与写入对象的顺序一致(读取的对象需要进行强制类型转换)
  • 进行对象反序列化时,要通过serialVersionUID验证类和对象是否为同一版本(强烈建议显式声明serialVersionUID,但是对类的修改不能对对象的反序列化造成影响
  • 对象反序列化不会调用构造函数(这种对象就是传说中不是被new出来的对象!!
程序示例:
public class Test91 {

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

		// 对象序列化
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream("obj.ser"));
			oos.writeObject(new Person("k", 11));// 如果参数类型没有实现Serializable接口,发生NotSerializableException
			oos.writeObject(new Person("kk", 21));
			oos.writeObject(new Person("kkk", 31));
			// oos.writeObject(new Student());可序列化的类的子类是自动可序列化的
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (oos != null) {
				try {
					oos.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭资源失败");
				}
			}
		}

		// 对象的反序列化
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream("obj.ser"));
			Person p1 = (Person) ois.readObject();
			Person p2 = (Person) ois.readObject();
			Person p3 = (Person) ois.readObject();
			ArrayList<Person> list = new ArrayList<>();
			list.add(p1);
			list.add(p2);
			list.add(p3);
			for (Person person : list) {// 读取对象的顺序与写入对象的顺序一致
				System.out.println("非静态变量:" + person.getName());// 非静态变量的值被还原
				System.out.println("瞬时变量:" + person.getAge());// 瞬时变量会被赋默认值0
				System.out.println("静态变量:" + Person.getLength());// 静态变量的值不变
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (oos != null) {
				try {
					oos.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭资源失败");
				}
			}
		}
	}
}

class Person implements Serializable {// 如果要让该类对象可以被序列化,就实现Serializable接口
	/**
	 * 
	 */
	private static final long serialVersionUID = 393843429975524886L;

	private String name;
	private transient int age;// 反序列化之后会被赋默认值0
	private static int length = 100;

	public Person() {
		super();
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = 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 static int getLength() {
		return length;
	}

	public static void setLength(int length) {
		Person.length = length;
	}
}

class Student extends Person {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8780508815255118201L;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值