序列化与反序列化(对象流)

对象在文件的存取操作有两种流,ObjectInputStream & ObjectOutputStream ,说到对文件操作,肯定少不了文件字节流 ,FileInputstream & FileOutputStream ,对象流内置字节流,然后通过字节方式,传输对象。

ObjectInputStream 有 readObject( )    从文件中读出一个对象

ObjectOutputStream 有 writeObject( ) 向文件写入一个对象

类定义:

         

import java.io.Serializable;
 
public class User implements Serializable{//实现序列化接口
	/**
	 * 序列化版本,辨别这个类的标志
	 */
	private static final long serialVersionUID = -7829726230920543458L;
	private String username;
	public User() {
	}
	public User(String username) {
		this.username = username;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	@Override
	public String toString() {
		return "User [username=" + username + "]";
	}
}

 具体实现:

@Test
public void TestObject() throws Exception{
       File f =new File("user.txt");
        User user = new User("大飞哥");
    try(
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
    ){
        oos.writeObject(user);  //把user对象写入
        User us = (User) ois.readObject();//从文件中读取user
        System.out.println(us.toString());//输出
    }
}

 

结果:

         

 

看控制台可以知道我们已经成功存取了一个对象。

实现序列化接口是对象输入输出到文件必要的途径。那么那个private static final long serialVersionUID = -7829726230920543458L;

有什么用呢,这个是识别是否为该类的编号。当多个类的对象存入文件或该类的方法和属性有改变时,文件内的对象属于该类的凭证。当我们不添加序列化编号时,jvm会自动添加一个随机的编号。当类有更变时,如删除重写的toString()方法,jvm无法辨别是否还是该类,又会因为序列化编号不匹配(jvm前后生成序列号随机),会有异常抛出,如:

Exception in thread "main" java.io.InvalidClassException: Test.User;

local class incompatible: stream classdesc serialVersionUID = -7829726230920543458,

local class serialVersionUID = 6005621513812223924

所以我们在实现序列化接口时就应该添加序列化编号

添加了确定的序列化,从文件中读取的对象就可以使用新添加的方法和属性。

现在删除我们重写的toString方法(),看看可不可以正常使用呢。

结果当然是ok:

        

如果我们不想让某些数据被记录进去该怎么办呢,我们可以添加transient关键字声明。

我们现在给username添加关键字,具体实现:

private transient String username;

其他代码不变,结果:

        

那么我们可不可以把 多个对象的集合ArrayList对象存进去呢,答案时可以的。

具体实现:

@Test
public void TestObject() throws Exception{
	File f =new File("user.txt");
	User user = new User("大飞哥");
	User user2 = new User("小飞哥");
	List<User> list = new ArrayList<User>();
	list.add(user);
	list.add(user2);
	try(    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
	){
		oos.writeObject(list);
		List<User> l=(List<User>)ois.readObject();//类型转化的警告
		for (int i = 0; i < l.size(); i++) {//输出所有信息
			System.out.println(l.get(i).toString());
		}
	}
}

结果:

        

成功了,当然千万不要忘记加泛型哦,标明类型是种好习惯,也是让java虚拟机知道这是储存什么类型到数据,后面使用就不用强制转换。<完>

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值