【问题标题】:Java: Modifying Objects by Method Call [duplicate]Java:通过方法调用修改对象
【发布时间】:2018-05-21 20:24:57
【问题描述】:

我已经读过无数遍了,在 Java 中,传递给方法的参数不能被方法修改。尽管如此,我发现我可以修改我创建的对象,而不是 Java 对象。考虑以下代码:

    // My Integer Object
    class MyInteger {
        Integer val;
    }

    // Change Java Object
    public void test1() {
        Integer intval;      // Integer object
        intval = 123;
        setInteger( intval );       // THIS DOESN'T WORK

        TTY.putR( "Integer Object="+intval);
    }

    // Change My Object
    public void test2() {
        MyInteger myInt;    // MyInteger object
        myInt = new MyInteger();
        myInt.val = 456;
        setMyInteger( myInt );      // THIS WORKS!

        TTY.putR( "MyIntegerObject=" + myInt.val );
    }

    // Set an Integer object
    public void setInteger( Integer val) {
        val = 888;
    }

    // Set a MyInteger object
    public void setMyInteger( MyInteger myint) {
        myint.val = 999;
    }

test1 不起作用,正如我已被警告的那样。但是 test2 工作得很好。 AFAIK,都是对象并通过引用传递。那么为什么一个有效而另一个无效呢? (注:TTY 是我的打印功能)

【问题讨论】:

  • 因为不能更新调用者的引用,而Integer不可变的。
  • 当然你可以修改你收到的对象,但是你不能修改调用者用来给你对象的引用。

标签: java methods parameter-passing


【解决方案1】:

您要么阅读了错误的内容,要么误解了您被告知的内容。

如果将“a”传递给 java 方法,则不能让方法将“a”更改为“a”以外的其他内容。但是,您可以修改“a”。

换句话说,您不能创建与“a”相同类的对象并返回它来代替“a”。返回由该方法创建的对象的唯一方法是在传递给该方法的对象中放置一个对该新对象的引用,或者将其作为该方法的返回值返回。

【讨论】:

  • 这解释了我看到的最好的东西。我认为对象总是通过引用传递,但我猜你所说的是传递的对象是原始的副本,所以该方法只是修改副本。对吗?
  • 不,恰恰相反。对象是通过引用传递的,也就是将指向对象的指针传递给方法。该方法不能更改该指针。但是该方法可以使用指针来更改对象内的内容,并且这些更改对调用者以及拥有该引用的任何人都是可见的。当您的程序执行MyClass o = new MyClass(); 时,变量o 现在包含对MyClass 的对象实例的引用;我们将o 称为对象,但它实际上是一个对象引用。当我们将“o”传递给方法时,我们传递的是引用。
【解决方案2】:

我见过的最好的解释方式:

你传递一个指向内存地址 P 的对象 A。

A ===> P

当你通过 A.foo = bar 修改 A 时,A 仍然指向 P,所以 P 处的对象的属性 foo 发生了变化。但是,假设您想完全重新分配 A,A = new MyCoolObject() 也是如此。这意味着

P_New P

所以当你通过 A.foo = bar 修改 A 时,A 不再指向 P,所以 P_New 处的对象的属性 foo 改变了,但 P 处的对象保持不变。 这意味着当您退出该方法并返回到调用该方法的任何父级时,A 将完全不变。

免责声明:大约 5 年前,我在另一篇 Stack Overflow 文章中看到了这个,我懒得找到它。如果你现在正在阅读这篇文章并且你是写这篇文章的人,谢谢,并原谅我随意的抄袭。

【讨论】:

    【解决方案3】:

    我认为您对按引用传递与按值传递感到困惑。阅读this 以帮助清除它。

    您可能还误解了您所阅读的内容。可变对象可以在任何地方发生变异——在它创建的地方或通过它传递到的方法。

    祝你好运。

    【讨论】:

      【解决方案4】:

      Java 是一种按值传递的语言。当您使用参数调用任何方法时,它会创建新变量并且您正在更改此变量。

      你也可以看看这个, Is Java "pass-by-reference" or "pass-by-value"?

      【讨论】:

        【解决方案5】:

        因为 MyInteger val 是一个公共变量。所以任何人都可以修改它。

         // Change MyInteger object
            public void setMyInteger( MyInteger val) {
                val.val = 999;  // ACCESING TO A PUBLIC VAR and SETTING IT
            }
        
        // Change an Integer object
        public void setInteger( Integer val) {
            val = 888; // Accesing to the value of the Variable and not modifing it
        }
        

        【讨论】:

          猜你喜欢
          • 2013-08-28
          • 2013-09-18
          • 1970-01-01
          • 1970-01-01
          • 2023-03-14
          • 1970-01-01
          • 2017-11-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多