学习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学习过程中的收获