繁体   English   中英

反直觉对象参数行为

[英]Counter Intuitive Object Parameter Behaviour

我很清楚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

提前致谢。

一些概念:

  • 对象是具有数据和行为的构造。
  • 变量是存储值的构造。
  • 对象引用是引用对象的值。
  • 引用类型的变量(不是原始类型的所有类型)将对象引用存储为其值。
  • 当您访问字段或从变量调用方法时,JVM取消引用对象引用的值,获取对象,并为您执行访问或调用。

最后一点是您在testCheck方法中正在做的事情。 也,

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

将对象作为参数传递不会将整个对象复制到新变量中,而只是传递该对象引用吗?

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

在Java中,参数始终按值传递,因此test实际上是test1的副本。 您犯的错误是,复制对象变量不会复制对象 它将引用复制到同一对象。 由于您要对同一对象实例上的字段进行突变,因此两个引用都将看到新状态。 相反,当您“更新”一个不可变的对象变量(如String ,您只是在引用一个新的对象实例。

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

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

testCheck(test1);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM