在Java中使用Externalizable接口进行反序列化[复制]

参见英文答案 > What is the difference between Serializable and Externalizable in Java?                                    11个
我正在学习Serializable和Externalizable接口,我看到,当重构Externalizable对象时,首先使用public no-arg构造函数创建一个实例,然后调用readExternal方法.如果对象不支持Externalizable,则通过从ObjectInputStream中读取Serializable对象来恢复它们.

我不明白为什么我们使用ObjectInputStream进行外部化,如果没有从那里引用对象?究竟是从ObjectInputStream中获取了什么?如果我们使用它,我想我们会从那里读到一些东西.

我还发现了这个关于Deserialization Externalizable或Serializable接口的图表

在Java中使用Externalizable接口进行反序列化[复制]

在反序列化过程中Serializable和Externalizable有什么区别?

我不明白为什么Externalizable对象不能通过以与Serializable对象相同的方式从ObjectInputStream中读取它们来恢复?

ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("employee.ser"))

我知道FileInputStream打开一个文件,根据文件中的数据创建一个字节序列. ObjectInputStream采用一系列字节,根据字节序列重新处理对象.

这是一个代码.

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class Employee implements Externalizable {

    private int id;
    private String name;
    private int age;

    public void Employee() {


    } 

    public int getId() {

        return id;
    }

    public void setId(int id) {

        this.id = id;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public int getAge() {

        return age;
    }

    public void setAge(int age) {

        this.age = age;
    }

    public String toString() {

        return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

    public void writeExternal(ObjectOutput oo) throws IOException {

        System.out.println("Inside writeExternal method");
        oo.writeInt(id); 
        oo.writeObject(name); 
    }

    public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException {

        System.out.println("Inside readExternal method");
        id = oi.readInt();
        name = (String) oi.readObject();
    }
}

ExternalizableWrite

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ExternalizableWrite {

    public static void main(String args[]) {

        ExternalizableWrite ew = new ExternalizableWrite();
        ew.writeEmployeeObject();
    }

    private void writeEmployeeObject() {

        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("employee.ser"))) {

            Employee employee = new Employee();
            employee.setId(101);
            employee.setName("Peter"); 
            employee.setAge(25); 

            System.out.println(employee);

            oos.writeObject(employee);  // write the specified object to the ObjectOutputStream

            System.out.println("Successfully written employee object to the file.\n");

        } catch (FileNotFoundException ex) {

            System.out.printf("ERROR: %s", ex); 

        } catch (IOException ex) {

            System.out.printf("ERROR: %s", ex); 
        }
    }
}

ExternalizableRead

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ExternalizableRead {

    public static void main(String args[]) {

        ExternalizableRead er = new ExternalizableRead();
        er.readEmployeeObject();
    }

    private void readEmployeeObject() {

        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("employee.ser"))) {

            Employee employee = (Employee) ois.readObject();

            System.out.println(employee);

            System.out.println("Successfully read employee objecct to the file.\n");

        } catch (FileNotFoundException ex) {

            System.out.printf("ERROR: %s", ex);

        } catch (IOException | ClassNotFoundException ex) {

            System.out.printf("ERROR: %s", ex);
        } 
    }
}

解决方法:

What is the difference between Serializable and Externalizable at the deserialization process?

根据ObjectInputStream的实现,Externalizable对象的处理方式与Serializable对象不同,如预期:

if (desc.isExternalizable()) {
    readExternalData((Externalizable) obj, desc);
} else {
    readSerialData(obj, desc);
}

正如您所料,readExternalData方法为正在反序列化的对象调用Externalizable#readExternal,而readSerialData方法只是对序列化字段进行反序列化.

I don’t understand why we use ObjectInputStream for Externalization if the object isn’t readed from there?

我不确定你在问什么,但是ObjectInputStream确实处理了Externalizable对象,如上所示.

I don’t understand why the Externalizable objects aren’t restored by reading them from an ObjectInputStream in the same way like Serializable objects?

因为Externalizable对象强制您手动序列化和反序列化它们,而Serializable会尝试序列化所有非静态和非瞬态字段.

上一篇:C#/VB.NET 在PDF中添加文件包(Portfolio)


下一篇:java – ObjectStream:有没有办法将序列化对象作为属性映射读取?