JAVA对象序列化(代码示范)

如何对一个java对象进行序列化?首先,对象的类需要实现Serializable接口,其次对象的域也必须都实现了Serializiable接口,最后可以使用ObjectOutputStream将对象序列化成字节流,流向网络或者文件。

以上是每个java程序员都知道的。但接下来稍微深入一些,可能会淘汰一批java程序员。首先列出关键字:transient, readObject(), writeObject(), readResolve(), serialVersionUID.

在需要序列化的对象中,存在一些域,并不需要序列化,因为对这些域序列化毫无意义,比如,对一个文件的引用,将其序列化不如将文件的路径存储下来,在对象反序列化的时候,使用文件路径重新创建文件的引用。对于此类域,可以使用关键字transient对其修饰。这样序列化程序将跳过此域。如果对象的类声明了writeObject()和readObject()方法,序列化程序将会调用对象的这两个方法。如下面的code,Employee的writeObject将File的绝对路径写入序列化流中,然后在反序列话时,读出文件绝对路径,重新对其实例化。

此外,有一些对象,比如单例,或者枚举。由于反序列化,导致单例变多例,枚举不再相等。此时,可以使用readResolve方法来解决此问题。readResolve()方法在readObject()之后,将反序列化实例返回。如下面的code,EmployeeType反序列化后,依旧保持枚举项可以用==来判断。

最后讲一下serialVersionUID。它代表两个类是相兼容的。如果一个实例序列化的时候用的是版本1.0的类,反序列化的时候,类版本已经升级为2.0,为了能使得向前兼容,可以将升级的类的serialVersionUID与之前版本的保持一致。这样,可以将版本1.0的实例反序列化成2.0版本。

执行类

public class SerializationTest {

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        Employee tracy = new Employee("Tracy", EmployeeType.SECRETARY, "tracy.contract");
        Manager bill = new Manager("Bill", EmployeeType.MANAGER, "bill.contract", tracy);
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("bill.data"));
            oos.writeObject(bill);
            
            
            ois = new ObjectInputStream(new FileInputStream("bill.data"));
            Manager billCopy = (Manager) ois.readObject();
            System.out.println(billCopy.getType() == EmployeeType.MANAGER);
            System.out.println(billCopy.getName());
            System.out.println(billCopy.getContract().getName());
            
            System.out.println(billCopy.getSecretary().getType() == EmployeeType.SECRETARY);
            System.out.println(billCopy.getSecretary().getName());
            System.out.println(billCopy.getSecretary().getContract().getName());
        } finally {
            if (oos != null) oos.close();
            if (ois != null) ois.close();
        }
    }
}
EmployeeType
package serialization;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;

public class EmployeeType implements Serializable {
    private static final long serialVersionUID = 446408774918722110L;
    
    public static final EmployeeType EMPLOYEE = new EmployeeType("employee");
    public static final EmployeeType HR = new EmployeeType("hr");
    public static final EmployeeType MANAGER = new EmployeeType("manager");
    public static final EmployeeType SECRETARY = new EmployeeType("secretary");
    
    private EmployeeType(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
    
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        
    }
    
    private Object readResolve() throws ObjectStreamException {
        if ("employee".equals(this.name)) return EmployeeType.EMPLOYEE; 
        if ("manager".equals(this.name)) return EmployeeType.MANAGER;
        if ("secretary".equals(this.name)) return EmployeeType.SECRETARY;
        return EmployeeType.EMPLOYEE;
    }
    
    private String name;

}

Employee

public class Employee implements Serializable {
    private static final long serialVersionUID = 4227138074044013136L;
    
    private String name;
    private EmployeeType type;
    private transient File contract;
    
    public Employee(String name, EmployeeType type, String contractId) {
        this.setName(name);
        this.setType(type);        
        String filepath = contractId+".txt";
        this.setContract(new File(filepath));
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public EmployeeType getType() {
        return type;
    }

    public void setType(EmployeeType type) {
        this.type = type;
    }

    public File getContract() {
        return contract;
    }

    public void setContract(File contract) {
        this.contract = contract;
    }
    
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeUTF(this.contract.getAbsolutePath());
    }
    
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        String path = in.readUTF();
        this.contract = new File(path);
    }

}

Manager

public class Manager extends Employee{
    private static final long serialVersionUID = 7105104278002669570L;
    private Employee secretary;
    
    public Manager(String name, EmployeeType type, String contractId, Employee secretary) {
        super(name, type, contractId);
        this.setSecretary(secretary);
    }

    public Employee getSecretary() {
        return secretary;
    }

    public void setSecretary(Employee secretary) {
        this.secretary = secretary;
    }

}

你可能感兴趣的:(java,Serializable,序列化)