欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习Java序列化的一些收获

程序员文章站 2022-05-19 22:07:17
...

1.修改默认的序列化机制:

       在java中有些对象是不能够用默认的序列化机制来写入磁盘的,如Rectangle2D.Double、Rectangle2D.Float、Point2D.Double、Point2D.Float等类的对象。如果一个类的数据域包含了这些类对象,我们应该用transient关键字标记,表明这样的数据域不能被默认的序列化机制写入磁盘。如果我们要用ObjectOutputStream将这些对象的数据写入磁盘,并且想用ObjectInputStream将其读入到相应的对象中的时侯,我们就应该修改默认的序列化机制。

 

import java.awt.geom.Point2D;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


public class IOTest 
{
	@SuppressWarnings("deprecation")
	public static void main(String [] args) throws IOException, ClassNotFoundException
	{
		
		//修改默认的序列化机制
		System.out.println("---------------修改默认的序列化机制-----------------\n");
		LabeledPoint point=new LabeledPoint("Override default",new Point2D.Double(23.4,23.5));
		ObjectOutputStream outPoint=new ObjectOutputStream(new FileOutputStream("noDefault.txt"));
		outPoint.writeObject(point);
		outPoint.close();
		
		ObjectInputStream inPoint=new ObjectInputStream(new FileInputStream("noDefault.txt"));
		LabeledPoint savedPoint=(LabeledPoint)inPoint.readObject();
		inPoint.close();
		System.out.println(savedPoint==null?"savedPoint==null":savedPoint.toString());
		
	}
}
@SuppressWarnings("serial")
class LabeledPoint implements Serializable
{
	private String label;
	private transient Point2D.Double point;
	
	public LabeledPoint(String l,Point2D.Double p)
	{
		label=l;
		point=p;
	}
	
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
	{
		in.defaultReadObject();
		double x=in.readDouble();
		double y=in.readDouble();
		point=new Point2D.Double(x,y);
		System.out.println("call LabeledPoint.readObject()");
	}
	
	private void writeObject(ObjectOutputStream out) throws IOException
	{
		out.defaultWriteObject();
		out.writeDouble(point.getX());
		out.writeDouble(point.getY());
		System.out.println("call LabeledPoint.writeObject()");
	}
	
	@Override
	public String toString()
	{
		return label+(point==null?"":("("+point.getX()+","+point.getY()+")"))+"\n";
	}
}

  

 

 

  我们还有另外一种修改默认的序列化机制的方法,那就是实现Externalizable接口。注意:用这种方法时一定要为实现了Externalizable接口的类提供一个默认的构造函数。因为再度入对象时,对象流将用默认的构造函数创建一个对象,然后调用readExternal方法。

 

 

import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class IOTest 
{
    	//实现Externalizable接口
		System.out.println("---------------实现Externalizable接口----------------\n");
		Employee em=new Employee("Harry",3434.434,new Date());
		ObjectOutputStream outEm=new ObjectOutputStream(new FileOutputStream("externalizable.txt"));
		outEm.writeObject(em);
		outEm.close();
		
		ObjectInputStream inEm=new ObjectInputStream(new FileInputStream("externalizable.txt"));
		Employee savedEm=(Employee)inEm.readObject();
		inEm.close();
		System.out.println(savedEm);
	}
}
class Employee implements Externalizable
{
	public Employee()
	{
		
	}
	public Employee(String name,double salary,Date hireDay)
	{
		this.name=name;
		this.salary=salary;
		this.hireDay=hireDay;
	}
	
	@Override
	public void readExternal(ObjectInput in)throws IOException
	{
		name=in.readUTF();
		salary=in.readDouble();
		hireDay=new Date(in.readLong());
		System.out.println("调用Employee.readExternal()");
	}
	
	@Override
	public void writeExternal(ObjectOutput out)throws IOException
	{
		out.writeUTF(name);
		out.writeDouble(salary);
		out.writeLong(hireDay.getTime());
		System.out.println("调用Employee.writeExternal()");
	}
	
	@Override
	public String toString()
	{
		return "Employee:"+name+" "+salary+" "+hireDay;
	}
	
	private String name;
	private double salary;
	private Date hireDay;
	
}

 

相关标签: Java