如何使用两个引用对对象进行反序列化?

时间:2017-09-27 07:20:13

标签: java serialization

继续this question;

请举一个简短的例子,说明如何使用两个引用对一个对象进行反序列化。

我已经包含了以下代码,因此所有答案都引用了相同的对象名称。

public class Person implements Serializable{
    private String name;
    private int age;
    private boolean single;
    private int numKids;
    private final static long serialVersionUID = 1L;

    public Person(String name, int age, boolean single, int numKids) {
        this.name = name;
        this.age = age;
        this.single = single;
        this.numKids = numKids;
        this.surname = surname;
    }
}

假设如下:

  1. 已创建文本文件
  2. 我们创建了一个Person对象jim
  3. 还有另一个人 bob 引用了jim对象
  4. 已引用的问题描述了如何仅将jim写入文件。 bob引用不是。如果文件可能包含Person类的另外几个对象,那么我们如何读取jimbob的值?我们如何确保bob具有正确的值?

2 个答案:

答案 0 :(得分:2)

你好像有点困惑。您的Person类允许引用 另一个 Person对象。你需要在Person类中有一个 Person 字段才能到达那里!从这个角度来看,你的问题没有意义:jimbob将是两个完全独立的对象,并且序列化其中一个将完全不会序列化另一个!

但除此之外:通常情况下,当您在复数事物(如多人)中思考时,您会想到一个封闭的“容器”对象(如List<Person>)关于。那时你不处理单个Person对象 - 但在考虑序列化时使用这样的容器!

你正试图建立一个根本无法解决的人为例子。而是考虑Person类可能包含字段Person spouse的情况。然后alice可以引用bob。当你现在拥有那些Person对象,以及列表中的更多对象,并序列化该列表时 - 系统将确保alicebob仅被序列化一次。

答案 1 :(得分:0)

我对你的问题感到困惑 - 也许是因为我没有看到同一个对象和/或多个对象的序列化和反序列化有任何问题或者没有对任何对象的引用。

重点是序列化就像创建对象的副本(在文件系统或某个地方)。可以在内存中重新创建此副本(反序列化)。 您可以在内存中创建对象(反序列化)一次或多次。

类似于:

object A --serialization--> file A
file A --deserialization--> object A'
file A --deserialization--> object A"
对象A,A&#39;和A&#34;是不同的对象 - 但所有字段都具有相同的值。

如果对象A包含复杂的结构(可以序列化/反序列化),它也可以是另一个对象,那么同样的机制也适用于这些对象。

所有字段都具有相同的值,但对象将不同。

参见示例代码:

package test;

import java.io.Serializable;

public class Person  implements Serializable {
    int id;
    String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

和一种测试

package test;

import java.io.*;

public class Main {
    public static void main(String... args) {
        Person p1 = new Person(1, "aaa");
        Person p1a = null;
        Person p1b = null;
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.data"))) {
            oos.writeObject(p1);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (ObjectInputStream oos = new ObjectInputStream(new FileInputStream("test.data"))) {
            p1a = (Person) oos.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        try (ObjectInputStream oos = new ObjectInputStream(new FileInputStream("test.data"))) {
            p1b = (Person) oos.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        assert p1a != null && p1b != null;
        assert p1a.id == p1b.id;
        assert p1.id == p1b.id;
        assert p1.name.equals(p1a.name);
        assert p1a.name.equals(p1b.name);

        System.out.println(String.format("Three different object: %s, %s, %s", p1, p1a, p1b));


    }
}

PS。如何在内存中复制/存储/管理java.lang.String个对象,这是不同的故事。