为什么在序列化/反序列化的情况下只创建一个父对象

时间:2017-04-17 07:28:47

标签: java serialization deserialization

为什么在序列化/反序列化

的情况下只创建一个父对象
//superclass A 
//A class doesn't implement Serializable
//interface.
class A 
{
    int i;

    // parameterized constructor
    public A(int i)
    {
        this.i = i;
    }

    // default constructor
    public A()
    {
        i = 50;
        System.out.println("A's class constructor called");
    }
}

// subclass B implementing Serializable interface
class B extends A implements Serializable
{
    int j;

    public B(int i, int j)
    {
        super(i);
        System.out.println("B.B()");
        this.j = j;
    }
}

// Driver class
public class SerializationWithInheritanceExample
{
    public static void main(String[] args) throws Exception
    {
        B b1 = new B(10, 20);

        System.out.println("i = " + b1.i);
        System.out.println("j = " + b1.j);

        // Serializing B's(subclass) object
        try (FileOutputStream fos = new FileOutputStream("abc.ser");
                ObjectOutputStream oos = new ObjectOutputStream(fos))
        {
            // Method for serialization of B's class object
            oos.writeObject(b1);
        }

        System.out.println("Object has been serialized\n");

        // Reading the object from a file
        readObject();
        readObject();
        readObject();

    }

    static void readObject()
    {
        // Reading the object from a file
        try (FileInputStream fis = new FileInputStream("abc.ser"); ObjectInputStream ois = new ObjectInputStream(fis))
        {
            // Method for de-serialization of B's class object
            B b2 = (B) ois.readObject();

            System.out.println("HasCode of A:"+ b2.getClass().getSuperclass().hashCode() +" | HasCode of B:"+b2.hashCode());

            System.out.println("i = " + b2.i);
            System.out.println("j = " + b2.j);
        } catch (IOException | ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}

输出

B.B()
i = 10
j = 20
Object has been serialized

A's class constructor called
HasCode of A:1311053135 | HasCode of B:1705736037
i = 50
j = 20
A's class constructor called
HasCode of A:1311053135 | HasCode of B:455659002
i = 50
j = 20
A's class constructor called
HasCode of A:1311053135 | HasCode of B:250421012
i = 50
j = 20

虽然B对象的反序列化多次,但只创建了A类父对象的一个​​对象。 为什么只创建一个对象?

3 个答案:

答案 0 :(得分:1)

您没有调用hashCode()实例的A方法,而是调用类A的实例,在大多数情况下,只有一个类对象的实例。

让我们分解:

b2               // instance of B
.getClass()      // Class<B>
.getSuperclass() // Class<A>
.hashCode()      // hash code of Class<A>

甚至无法为A&#39;的部分获取单独的哈希码。 B的实例:只有一个对象,它只有一个哈希码。

创建B时,只创建一个对象,而不是像您想象的那样创建两个对象。该对象包含B的所有内容,其中包含A的部分内容。

答案 1 :(得分:1)

当您致电b2.getClass().getSuperclass()时,您的实例类型为Class<A>。这只是A类的对象,它包含有关类A声明的信息。当您调用b2.hashCode()时,您有实例的哈希码,它引用了b2

答案 2 :(得分:0)

在A的情况下,您获得类的哈希码 A.在B的情况下,您获得实例 B的哈希码。并且您的3个B实例正在共享1个超类A(连同B类)。因此,例如,如果您调用b2.getClass().hashcode() 3次,则所有这些方法调用的输出也相等,因为您有1个B类。