时间:2022-09-06 13:55:12 | 栏目:JAVA代码 | 点击:次
首先亮明Java中方法参数传递的规则,这两点很重要:
上面这两条比较简单,笔者就不展开说了,这里只说一点,关于方法中引用的传递,很多人会踩坑,如下:
我们先以数组举例,如下代码,很简单的几行,大家猜一下会最终输出的结果是什么样子的呢?
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)); } }
根据第二条规则如果实参是对象集合或者数组,则实参会改变(传的是引用),大家很容易想到,这个实参为数组,传的是引用,其值会改变,那就大错特错了。这个只会在方法中短暂改变数组的值,回到main方法栈中还是{0}。
实际输出如下:
[1, 2, 3]
[0]
Process finished with exit code 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]
Process finished with exit code 0
熟悉C或C++的同学可以类比int *const(允许更改存储在地址中的值),而不是int const*(允许指针指向其他地址)。
Java 形参和实参的区别:
形参 :就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的。 形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元。 因此,形参只在方法内部有效,所以针对引用对象的改动也无法影响到方法外。
实参 :就是实际参数,用于调用时传递给方法的参数。实参在传递给别的方法之前是要被预先赋值的。 在本例中 swap 方法 的numa, numb 就是形参,传递给 swap 方法的 a,b 就是实参
注意:在值传递调用过程中,只能把实参传递给形参,而不能把形参的值反向作用到实参上。在函数调用过程中,形参的值发生改变,而实参的值不会发生改变。而在引用传递调用的机制中,实际上是将实参引用的地址传递给了形参,所以任何发生在形参上的改变也会发生在实参变量上。
总结