0

从数据文件加载保存的序列化对象时,我对变量的引用有问题。引用同一对象的所有变量似乎都不会随着更改而更新。我在下面截取了一个代码来说明问题。

    Tournament test1 = new Tournament();
    Tournament test2 = test1;

    try {
        FileInputStream fis = new FileInputStream("test.out");
        ObjectInputStream in = new ObjectInputStream(fis);

        test1 = (Tournament) in.readObject();

        in.close();

    }
    catch (IOException ex){
        Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (ClassNotFoundException ex){
        Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
    }

    System.out.println("test1: " + test1);
    System.out.println("test2: " + test2);

运行此代码后, test1 和 test2 不再引用同一个对象。据我所知,他们应该这样做,因为在 test2 的声明中,它是对 test1 的引用。当 test1 更新时 test2 应该反映更改并在代码中调用时返回新对象。我是否在这里遗漏了一些重要的东西,或者我对 Java 中的变量引用是如何工作的有误解?

4

4 回答 4

3

我是否在这里遗漏了一些重要的东西,或者我对 Java 中的变量引用是如何工作的有误解?

很可能您误解了所教的内容,或者被教错了。所有引用类型的变量(即不是原始类型)都引用directly一个对象。

Tournament test1 = new Tournament();

创建一个新实例Tournamenttest1引用它。

Tournament test2 = test1;

test1从to复制引用test2,使它们都引用同一个对象。

test1 = (Tournament) in.readObject();

Makestest1引用已从流中反序列化的不同对象,但test2仍引用原始对象。

于 2010-04-15T17:05:06.900 回答
0

当您使用序列化解组一个对象并将其分配给一个变量时,您将旧引用(在您的情况下为 a new Tournament())替换为新对象。所以test2将指向原始对象Tournament,而test1将引用刚刚未序列化的对象。

就像这样做:

Tournament t1 = new Tournament();
Tournament t2 = t1;

t1 = new Tournament();

t1 == t2吗?当然不是..

于 2010-04-15T17:01:42.270 回答
0

问题在于 Java 通过引用传递和分配的概念。它没有。Java 按值传递和分配。碰巧的是,对于引用类型,传递的值是一个引用。

不同之处在于:假设您有一些测试代码

Tournament test1 = new Tournament();
Tournament test2 = test1;

test1 = new Tournament();
System.out.println(test1 == test2 ? "Equal" : "Not Equal");

如果 Java 通过引用传递,它将打印Equal,因为它test2只是test1. 但是,因为 Java 按值传递,所以它会打印Not Equal.

于 2010-04-15T17:13:19.770 回答
0

你不是test1在任何地方“更新”。

这一行正在分配一个从输入流中读取的不同类型Tournament的对象,并将这个新对象分配给test1

test1 = (Tournament) in.readObject();

同时,test2仍然指向在代码块开始时分配的原始对象。

于 2010-04-15T17:16:02.363 回答