Serializable序列化(一)

package serializ;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 类要实现序列化,必须实现Serializable接口 <br>
 * 但该接口并没有任何方法要实现 <br>
 * 一般序列化可以保存到字节数据或者文件 <br>
 * 比如为了实现对象在系统间传输
 * 
 * @author yli
 * 
 */
public class Employee implements Serializable {

	/**
	 * 一旦实现Serializable接口,就应该定义默认的序列ID
	 * 因为类可以不断升级,比如增加字段或者增加方法
	 * 那么老版本的类和新版本的类,如果通过序列化关联起来
	 * 就要求新老版本的类拥有相同的 serialVersionUID
	 * 
	 * @see 在JDK的bin目录,有serialver.exe程序,可以用于生成每个类的UID
	 */
	private static final long serialVersionUID = 5128673904770381297L;

	protected String name;

	protected double salary;

	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
	}

	public String toString() {
		return String.format("{name:%s,salary:%s}", this.name, this.salary);
	}
	
	public Employee getEmp() {
		return this;
	}

	public static void main(String[] args) {
		String file = "src/serialize.dat";
		Employee emp1 = new Employee("yli", 10000d);

		System.out.println("==>write Employee");
		System.out.println(emp1);
		writeObject(emp1, file);

		System.out.println("==>read Employee");
		Employee emp2 = (Employee) readObject(file);
		System.out.println(emp2);

		System.out.println("============================");

		System.out.println(String.format("(emp1==emp2)===>%s", emp1 == emp2));
		
		// 反序列化之后两个对象不会相等
		// 因为反序列化回来内存地址肯定不一样,比如在另一台机器上反序列化
		// 地址是不可能相等的,那如果A对象被B、C对象引用
		// A、B、C 全部序列化了,那反序列化回来之后:B、C持有的A对象还是相等的吗?
		// Java的序列化机制保证了反序列化回来之后持有的A对象想的
		Manager m1 = new Manager("m1", 15000d);
		m1.setEmp(emp1);
		
		Manager m2 = new Manager("m2", 20000d);
		m2.setEmp(emp1);
		
		Employee[] emps1 = new Employee[]{emp1,m1,m2};
		System.out.println("==>write Employee[]");
		writeObject(emps1, file);

		System.out.println("==>read Employee[]");
		Employee[] emps2 = (Employee[]) readObject(file);
		
		// 打印结果显示m1和m2持有的emp对象是相同的
		// 因为在序列化每个对象时,会为这对象产生唯一的序列号Id
		// 比如emp1序列化成功后,产生序列Id:001
		// 那么m1和m2在序列化时,因为关联到同一个employee对象
		// 且发现emp1对象已经序列化了,则m1和m2都关联到 emp1的Id:001 上面即可
		// 反序列化过程也要依赖每个对象的Id
		System.out.println(String.format("(emps2[0]==emps2[1].getEmp()===>%s)", emps2[0]==emps2[1].getEmp()));
		System.out.println(String.format("(emps2[0]==emps2[2].getEmp()===>%s)", emps2[0]==emps2[2].getEmp()));
		
	}

	// 序列化对象
	private static void writeObject(Object obj, String file) {
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
			oos.writeObject(obj);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// 反序列化
	private static Object readObject(String file) {
		ObjectInputStream ois = null;
		Object obj = null;
		try {
			ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
			obj = ois.readObject();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return obj;
	}
}

class Manager extends Employee {
	
	private static final long serialVersionUID = -3030759793812915423L;
	
	private Employee emp;

	public Manager(String name, double salary) {
		super(name, salary);
	}

	public Employee getEmp() {
		return emp;
	}

	public void setEmp(Employee emp) {
		this.emp = emp;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值