在Java中从文件加载对象时出现变量引用问题
从数据文件加载保存的序列化对象时,变量引用有问题。引用同一对象的所有变量似乎不会随更改而更新。我在下面截取了一段代码来说明这个问题
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中变量引用是如何工作的
# 1 楼答案
你没有在任何地方“更新”
此行将从输入流中读取类型为
Tournament
的不同的对象,并将此新对象分配给test1
:同时,
test2
仍然指向在代码块开始时分配的原始对象# 2 楼答案
问题在于Java通过引用传递和分配的概念。但事实并非如此。Java通过值进行传递和赋值。碰巧,对于引用类型,传递的值是一个引用
区别在于: 假设你有一些测试代码
如果Java通过引用传递,它将打印
Equal
,因为test2
只是test1
的别名。然而,因为Java是按值传递的,所以它会打印Not Equal
# 3 楼答案
当你用序列化来解组一个对象并将其分配给一个变量时,你就用新对象替换了旧的引用(在你的例子中是
new Tournament()
)。。所以test2
将指向原始的Tournament
,而test1
将引用刚刚未序列化的对象就像做:
会
t1 == t2
?当然不是# 4 楼答案
很可能你误解了别人教你的东西,或者别人教错了什么。引用类型的所有变量(即非基元类型)都将
directly
引用到一个对象创建
Tournament
的新实例,并使test1
引用它将引用从
test1
复制到test2
,使它们都引用同一个对象使
test1
引用已从流中反序列化的不同对象,而test2
仍然引用原始对象