从数据文件加载已保存的序列化对象时,我对变量的引用有问题。引用同一对象的所有变量似乎都没有更新。我在下面剪了一个代码,说明了问题。
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中的变量引用如何工作有误解?
答案 0 :(得分:3)
我错过了一些必不可少的东西 或者我是如何被误导的 Java中的变量引用有效吗?
你很可能误解了你的教学内容,或者被教导错了。引用类型的所有变量(即非基本类型)都将directly
引用到对象。
Tournament test1 = new Tournament();
创建Tournament
的新实例,并使test1
引用它。
Tournament test2 = test1;
将引用从test1
复制到test2
,使它们都引用同一个对象。
test1 = (Tournament) in.readObject();
使test1
引用已从流中反序列化的其他对象,而test2
仍然引用原始对象。
答案 1 :(得分:0)
当您使用序列化解组对象并将其分配给变量时,您将旧引用(在您的情况下为new Tournament()
)替换为新对象..因此test2
将指向原始对象Tournament
,而test1
将引用刚刚反序列化的对象..
就像在做:
Tournament t1 = new Tournament();
Tournament t2 = t1;
t1 = new Tournament();
会t1 == t2
吗?当然不是..
答案 2 :(得分: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
。
答案 3 :(得分:0)
您无法在任何地方“更新”test1
。
这一行指定了一个不同的对象,它正在从输入流中读取Tournament
,并将这个新对象分配给test1
:
test1 = (Tournament) in.readObject();
同时,test2
仍然指向在代码块开头分配的原始对象。