运维开发网

Java踩坑方法中形参和实参的传递

运维开发网 https://www.qedev.com 2022-04-25 14:46 出处:网络
这篇文章主要给大家介绍了关于Java必踩的坑之方法中形参、实参传递的相关资料,以及Java形参和实参的区别,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

这篇文章主要给大家介绍了关于Java必踩的坑之方法中形参、实参传递的相关资料,以及Java形参和实参的区别,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

首先,明确Java中方法参数传递的规则很重要。这两点是:

如果实参是基本类型(包括包装类型)或者String,则实参不会变(传的是值);如果实参是对象集合或者数组,则实参会改变(传的是引用)。

以上两篇比较简单,我就不展开了。在这里,我只说一件事。很多人会践踏方法中引用的传递,如下:

我们以一个数组为例。下面的代码是几行简单的代码。你能猜到最后的输出是什么样的吗?

public class PassByValueDemo { public static void main(String[] args) { int[] i = {0}; new PassByValueDemo().Demo(i); // 这个地方还是0 System.out.printf(Arrays.toString(i)); } public void Demo(int[] i){ // 这个实参为数组,传的是引用,其值会改变??? nonono,只是在这个方法中改变了,回到main方法栈中还是{0}。 i = new int[]{1,2,3}; System.out.println(Arrays.toString(i)); }}

根据第二个规则,如果参数是一组对象或一个数组,参数将发生变化(引用被传递)。大家很容易认为这个参数是一个数组,但是引用传递了,它的值就会发生变化。这是一个大错误。这只会在方法中短暂地更改数组的值,它将返回到主方法堆栈或{0}。
实际输出如下:

[1,2,3]
[0]
进程结束,退出代码为0

为什么会这样?具体分析如下:

我们先看main方法中第一行操作int [] i ={0},这个操作会在内存中开辟一个4字节大小的内存空间,然后返回其该数组的首地址,我们假设该数组的首地址值为0x1111,那么此时i就指向了内存中0x1111这么一个空间。内存地址为0x1111的空间存储了0;继续往下指看,调用Demo方法,此时会保存mian方法栈的状态,包括i在mian方法中指向的内存空间,这里点很重要,很重要,重要,重要的事情说三遍。在Demo方法中 new Int[] {1,2,3},这个操作会重新在内存中开辟一个空间,然后返回该数组的首地址的值,我们把这个地址值假设为0x2222,内存为0x2222存储了1,2,3;此时i的值指向了0x2222;那么这个时候输出i,当然会打印1,2,3;执行完了Demo方法,我们回到main方法中,此时从虚拟机栈中恢复刚才进入Demo方法前保存的栈信息,在进入Demo方法前i是指向0x1111这么一个地址空间,进入前已经保存了栈中的局部变量表中(局部变量表可参考笔者该篇博文:点击我),我们现在取出来,那么i的指向的就是0x1111,而不是0x2222,此时打印的是0x1111指向的值,也就是0;

虽然我们不能改变引用地址,但我们可以改变引用所指向的地址空中的值,如下所示:

public class PassByValueDemo { public static void main(String[] args) { int[] i = {0}; new PassByValueDemo().Demo(i); System.out.printf(Arrays.toString(i)); } public void Demo(int[] i){ i[0] = 1; System.out.println(Arrays.toString(i)); }}

输出结果:

[1]
[1]
进程结束,退出代码为0

熟悉C或C++的同学可以用int *const(允许改变存储在地址中的值)的类比来代替int const*(允许指针指向其他地址)。

Java形参和实参的区别:

参数:是一个形参,用来定义一个方法。它用于接收调用者传递的参数。参数只有在调用方法时,虚拟机才会分配内存单元,调用方法后释放分配的内存单元。因此,形参只在方法内部有效,所以对被引用对象的更改不会影响方法外部。

参数:实际参数,用于在调用时传递给方法。参数在被传递给其他方法之前被预先赋值。在这个例子中,numa、交换方法数量是形式参数,传递给交换方法的a和b是实际参数。

注意:在值传递的调用过程中,只能将参数传递给参数,不能将参数的值反向传递给参数。在函数调用过程中,形参的值会改变,但实参的值不会改变。在引用调用的机制中,实参引用的地址实际上是传递给形参的,所以任何发生在形参上的变化也会发生在实参变量上。

摘要

关于Java的踩坑方法中的形参和实参传递的这篇文章到此为止。关于Java中形参和实参传递的更多信息,请搜索源搜网之前的文章或者继续浏览下面的相关文章。

0

精彩评论

暂无评论...
验证码 换一张
取 消