【问题标题】:Counter Intuitive Object Parameter Behaviour反直观的对象参数行为
【发布时间】:2014-07-29 08:03:16
【问题描述】:

我很清楚 Java 按值传递参数,以及由于对象作为引用保存在变量中,因此当这些值是可变的时,如何更改对象值。我还理解的是,String 类包含不可变的对象。因此,为了测试我的理解,我决定编写一些代码,将对象作为参数传递给方法,更改其字符串和 int 变量,然后打印它。我预计,由于参数只是一个副本,因此这些更改不会影响传入的变量。作为参数传入一个对象是否不会将整个对象复制到一个新变量中,而只是传递该对象引用?这与几个消息来源告诉我的相反。这是有问题的代码:

public class Test {


    public int testVar = 20;
    public String testString = "Hello";

    public static void testCheck(Test test){
        test.testString = new String("GoodBye");
        test.testVar = 10;
    }

    public void printTest(){
        System.out.println("testVar: " + testVar + " testString: " + testString);
    }

    public static void main(String[] args) {
        Test test1 = new Test();
        test1.printTest();
        testCheck(test1);
        test1.printTest();

    }

}

输出:

testVar: 20 testString: Hello 

testVar: 10 testString: GoodBye 

预期:

testVar: 20 testString: Hello

testVar: 20 testString: Hello

提前致谢。

【问题讨论】:

    标签: java parameters pass-by-reference pass-by-value


    【解决方案1】:

    在Java中,参数总是按值传递的,所以test实际上是test1的一个副本。您犯的错误是复制对象变量不会复制 object;它将 reference 复制到同一个对象。由于您正在更改同一对象实例上的字段,因此两个引用都看到了新状态。相比之下,当您“更新”不可变对象变量时,例如 String,您只是在引用一个新的对象实例。

    顺便说一句,创建new String 而不是仅仅分配字符串文字很少有充分的理由。在这种情况下绝对没有。

    【讨论】:

      【解决方案2】:

      几个概念:

      • 对象是具有数据和行为的构造。
      • 变量是一种存储值的构造。
      • 对象引用是引用对象的值。
      • 引用类型的变量(所有非基本类型的类型)将对象引用存储为它们的值。
      • 当您访问字段或从变量调用方法时,JVM 会取消引用对象引用的值,获取对象,然后为您执行访问或调用。

      最后一点是您在 testCheck 方法中所做的事情。还有,

      • 方法参数是在方法定义中声明的变量。
      • 方法参数是您希望在调用方法时绑定到方法参数的值。
      • Java 传递(按值)并将对象引用的值绑定到方法参数。

      将对象作为参数传入不会复制整个对象 进入一个新变量,然后简单地传递该对象引用?

      这句话没有多大意义。您作为参数传递的是一个值。该值是对象引用,而不是对象。在您的方法中,您取消引用该对象引用以访问字段并调用被引用对象的方法。

      【讨论】:

        【解决方案3】:

        您正在将引用的副本传递给原始对象。实际上,您正在传递原始对象的引用,等等:

        testCheck(test1);
        

        您正在修改test1 对象的属性/变量。

        【讨论】:

          猜你喜欢
          • 2021-06-16
          • 2015-01-24
          • 2011-06-28
          • 2018-08-27
          • 1970-01-01
          • 1970-01-01
          • 2018-01-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多