首页>>后端>>java->聊聊 Java 中参数传递的原理!

聊聊 Java 中参数传递的原理!

时间:2023-12-02 本站 点击:0

今天,想和大家聊聊关于java中的参数传递的原理,参数的传递有两种,值传递和引用传递。

值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

基本类型传递

先来看看下面这段最基本的代码:

@Testpublicvoidtest(){intn=10;test01(n);System.out.println("最终结果n=="+n);}privatevoidtest01(intm){System.out.println("修改之前m=="+m);m=20;System.out.println("修改之后m=="+m);}

输出结果:

修改之前m==10修改之后m==20最终结果n==10

如果跟你预期的不同,那我想你还是没有理解参数的值传递与引用传递的原理。

结合生活中的场景,深入理解一下值传递和引用传递:

你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。

你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。

下面我们来画图更好的理解上述代码的例子:

当发生函数调用的时候 n 将自己传入到 test01 方法中,同时将自己的值复制了一份并赋值给了一个新变量 m 从图中可以看出这是 nm 两个变量没有一毛钱关系(m只是n的复制品),所以对 m 的修改并不会影响到 n

如果想要改变n的值,可以使用方法的返回值:

n=test01(n);

引用类型传递

下面来看看引用类型的传递:

publicclassDog{privateStringname;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicDog(Stringname){this.name=name;}@OverridepublicStringtoString(){return"Dog{"+"name='"+name+'\''+'}';}}@Testpublicvoidtest(){Dogdog1=newDog("小白");test01(dog1);System.out.println("最终结果dog=="+dog1);}privatevoidtest01(Dogdog){System.out.println("修改之前dog=="+dog);dog.setName("小黑");System.out.println("修改之后dog=="+dog);}

输出结果:

修改之前dog==Dog{name='小白'}修改之后dog==Dog{name='小黑'}最终结果dog1==Dog{name='小黑'}

为了方便大家理解,还是画图来分析一下:

test 方法中我们创建了一个 dog1 的对象,该对象存放于堆内存中,假设内存地址为 0x1120 ,于是 dog1 这个变量便应用了这块内存地址。

当我们调用 test01 这个方法的时候会在该方法栈中创建一个变量 dog ,这个 dog 变量是由原本的入参 dog1 复制而来,所以它所对应的堆内存依然是 0x1120

所以当我们通过 dog 这个变量修改了数据后,本质上修改的是同一块堆内存中的数据。从而原本引用了这块内存地址的 dog1 也能查看到对应的变化。

如果不理解上面的话,那么记住下面的两句话就行了:

传递引用类型的数据时,传递的并不是引用本身,依然是值;只是这个值是内存地址罢了。

因为把相同的内存地址传过去了,所以对数据的操作依然会影响到外部。

那我们继续看看下面的代码,这种情况能否改变参数的值

@Testpublicvoidtest(){Dogdog1=newDog("小白");test01(dog1);System.out.println("最终结果dog1=="+dog1);}privatevoidtest01(Dogdog){System.out.println("修改之前dog=="+dog);dog=newDog("小黑");System.out.println("修改之后dog=="+dog);}

输出结果:

修改之前dog==Dog{name='小白'}修改之后dog==Dog{name='小黑'}最终结果dog1==Dog{name='小白'}

假设 Java 是引用传递那最终的结果应该是打印 小黑 才对,从结果看这里依然是值传递。

还是画图来分析一下:

如果是引用传递,原本的 0x1120 应该是被直接替换为新创建的 0x1121 才对;而实际情况如上图所示,dog 直接重新引用了一个对象dog = new Dog("小黑"),两个对象之间互不干扰。

小结

Java中参数传递其实还是值传递的,只不过对于引用类型参数,值的内容是对象的引用。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/java/10498.html