形参 & 实参
参数在程序语言中分为实参和形参:
- 实际参数:用于传递给函数/方法的参数,必须有确定的值。
- 形式参数:用于定于函数/方法,接收实参,不需要有确定的值。
值传递 & 引用传递
程序设计语言将实参传递给函数的方法分为两种:
- 值传递:方法接收的是实参的值的拷贝,会创建副本。
- 引用传递:方法接收到的是实参所引用的对象在堆中的地址,不会创建副本,意味着修改形参会同时修改实参。
Java 的值传递
Java 中将实参传递给方法/函数的方式是值传递:
- 如果参数是基本数据类型,传递的是基本类型的字面量值的拷贝,会创建副本。
- 如果参数是引用类型,传递的是实参所引用的对象在堆中的内存地址的拷贝,同样也会创建副本。
传递基本类型参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
public static void main(String[] args) throws Exception { int n1 = 10; int n2 = 20; swap(n1, n2); System.out.println("n1 is " + n1); System.out.println("n2 is " + n2); }
public static void swap(int a, int b) { int temp = a; a = b; b = temp; System.out.println("a is " + a); System.out.println("b is " + b); }
|
在 swap 中 a、b 的值是从 n1、n2 复制过来的,相当于 n1、n2 的副本。所以无论怎么修改交换 a、b 的值,都不会改变 n1、n2 的值。
传递引用类型参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
public static void main(String[] args) throws Exception { int[] array = {1, 2, 3, 4, 5}; System.out.println(array[0]); change(array); System.out.println(array[0]); }
public static void change(int[] arr) { arr[0] = -1; }
|
当实际参数为引用类型时,方法会拷贝实参对象的地址值。change
方法中拷贝的是array
的地址,所以方法内部的arr
指向的是和array
同样的数组,对arr
的修改也会影响array
。
传递不可变类型参数
如果传递的引用类型是不可变的,那么即使方法内部进行了修改,也不会影响实参。以字符串为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public static void main(String[] args) throws Exception {
String string = "1234"; System.out.println(string); change(string); System.out.println(string); }
public static void change(String str) { str = "4321"; }
|
参考
- JavaGuide:Java 为什么只有值传递?
- Java 到底是值传递还是引用传递? - Hollis的回答 - 知乎