有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在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中变量引用是如何工作的


共 (4) 个答案

  1. # 1 楼答案

    你没有在任何地方“更新”

    此行将从输入流中读取类型为Tournament不同的对象,并将此新对象分配给test1

    test1 = (Tournament) in.readObject();
    

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

  2. # 2 楼答案

    问题在于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. # 3 楼答案

    当你用序列化来解组一个对象并将其分配给一个变量时,你就用新对象替换了旧的引用(在你的例子中是new Tournament())。。所以test2将指向原始的Tournament,而test1将引用刚刚未序列化的对象

    就像做:

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

    t1 == t2?当然不是

  4. # 4 楼答案

    Am I missing something essential here or have I been misstaught about how the variable references in Java works?

    很可能你误解了别人教你的东西,或者别人教错了什么。引用类型的所有变量(即非基元类型)都将directly引用到一个对象

    Tournament test1 = new Tournament();
    

    创建Tournament的新实例,并使test1引用它

    Tournament test2 = test1;
    

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

    test1 = (Tournament) in.readObject();
    

    使test1引用已从流中反序列化的不同对象,而test2仍然引用原始对象