【问题标题】:Object Reference passing in Java. Pass by reference working differently in different case?在 Java 中传递对象引用。通过引用传递在不同情况下的工作方式不同?
【发布时间】:2013-05-19 08:50:30
【问题描述】:

在玩 Java 时。如果一个对象被修改并被赋予一个值,我会看到不同的行为,如果它被分配一个新对象,我会看到不同的值。这是我为显示结果而编写的代码。

public class Test {

    int i;

    public Test(int j) {
        this.i = j;
    }

    public static void main(String[] args) {

        Test A = new Test(5);
        Test N = new Test(5);
        add(A);
        makeNew(N);
        System.out.println("Value of A.i= "+A.i);
        System.out.println("Value of N.i= "+N.i);

    }

    private static void add(Test t) {
        t.i+= 3;
        System.out.println("Inside method add() t.i= "+t.i);

    }

    private static void makeNew(Test t) {

        t = new Test(8);
        System.out.println("Inside method makeNew() t.i= "+t.i);

    }

}

这是上面代码的输出。

Inside method add() t.i= 8
Inside method makeNew() t.i= 8
Value of A.i= 8
Value of N.i= 5  

在上面的示例中,对象 A 被修改为值 8。对象 B 本身被赋予了一个新对象。但是只将它们召回对象 A 会显示新的价值。对象 B 显示旧值本身。它们不应该显示相同的值,因为两种情况都是通过引用传递的吗?我期待 A.i 和 N.i. 的值相同

【问题讨论】:

标签: java oop computer-science


【解决方案1】:

发生了什么:

Test A = new Test(5);
Test N = new Test(5);

add(A);  // method is add(Test t)

makeNew(N)// method is makeNew(Test t)

t = new Test(8);

System.out.println("Value of A.i= "+A.i);
System.out.println("Value of N.i= "+N.i);

【讨论】:

    【解决方案2】:

    每当您使变量等于一个对象,然后在该对象上的其他地方(例如通过另一个引用)使用 new 时,您设置为对象引用的变量不再指向新对象,但仍保留旧对象.因此,如果不同范围内的多个变量持有一个引用,它们都需要一种方法使它们等于新对象的任何内容,或者它们不再同步。

    【讨论】:

      【解决方案3】:

      我想这会让你怀疑清楚:

      你看到N仍然指向第一个对象

      【讨论】:

        【解决方案4】:

        在您的makeNew 中,您正在用您的new test(8) 对象覆盖对现有对象(作为参数传入)的引用。但是,这是makeNew 内部的本地对象,因此位于main(...) 内部的原始对象不受影响。

        【讨论】:

          【解决方案5】:

          Java 是按值传递的。您将对象的引用作为值传递,因此您可以修改该对象。但是,您不能修改对象的实际引用并使其指向其他对象。

          您的问题已经在这里得到解答:Is Java "pass-by-reference" or "pass-by-value"?

          【讨论】:

          • Java 不是按值传递的。只有原语是按值传递的。 OP 的对象不改变状态的原因是因为参数是对象的另一个引用,makeNew 只是将t 引用设置为另一个不影响N 的新对象
          • 不,您的投票不正确。看看我的链接的第一个答案。
          • 这是您在此链接中所指的内部语义。进一步阅读后,您所展示的只是是的,内存位置地址是按值传递的……当然是这样!显然,对于任何其他给定语言的指针也可以这样说。当我们谈论引用时,我们只是说对象是通过引用传递的(在潜台词中无需提及:凭借实际上是按值传递的内存地址)。这是最迂腐的,它无助于 OP 真正理解他的问题的答案。
          • 这个“内部语义”帮助我理解了将对象传递给函数时发生了什么,所以我猜它也会对他有所帮助。
          【解决方案6】:

          在 Java 中,您不传递实际对象,也不传递对对象的引用。 您将引用的副本传递给该对象。现在当您说

          makeNew(N);
          

          作为对new Test(5) 的引用的N 未传递,但其引用的副本 已传递。在 makeNew() 函数中,该副本指向某个新对象并适当地打印该值,但 N 仍将指向原始对象。

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-12
          • 2011-03-18
          • 2022-01-11
          • 2015-11-02
          • 2011-08-28
          • 1970-01-01
          • 2012-05-20
          • 2017-09-11
          相关资源
          最近更新 更多