# 形参 & 实参

参数在程序语言中分为实参和形参:

  • 实际参数:用于传递给函数/方法的参数,必须有确定的值。
  • 形式参数:用于定于函数/方法,接收实参,不需要有确定的值。

    # 值传递 & 引用传递

    程序设计语言将实参传递给函数的方法分为两种:

  • 值传递:方法接收的是实参的值的拷贝,会创建副本。

  • 引用传递:方法接收到的是实参所引用的对象在堆中的地址,不会创建副本,意味着修改形参会同时修改实参。

    # Java 的值传递

    Java 中将实参传递给方法/函数的方式是值传递:

  • 如果参数是基本数据类型,传递的是基本类型的字面量值的拷贝,会创建副本。

  • 如果参数是引用类型,传递的是实参所引用的对象在堆中的内存地址的拷贝,同样也会创建副本。

    | 传递基本类型参数

    ```java 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); }

  1. ```java
  2. a is 20
  3. b is 10
  4. n1 is 10
  5. n2 is 20

在 swap 中 a、b 的值是从 n1、n2 复制过来的,相当于 n1、n2 的副本。所以无论怎么修改交换 a、b 的值,都不会改变 n1、n2 的值。

| 传递引用类型参数

  1. public static void main(String[] args) throws Exception {
  2. int[] array = {1, 2, 3, 4, 5};
  3. System.out.println(array[0]);
  4. change(array);
  5. System.out.println(array[0]);
  6. }
  7. public static void change(int[] arr) {
  8. arr[0] = -1;
  9. }
  1. 1
  2. -1

当实际参数为引用类型时,方法会拷贝实参对象的地址值。change 方法中拷贝的是 array 的地址,所以方法内部的 arr 指向的是和 array 同样的数组,对 arr 的修改也会影响 array。

* 传递不可变类型参数

如果传递的引用类型是不可变的,那么即使方法内部进行了修改,也不会影响实参。以 String 为例:

  1. public static void main(String[] args) throws Exception {
  2. String string = "1234";
  3. System.out.println(string);
  4. change(string);
  5. System.out.println(string);
  6. }
  7. public static void change(String str) {
  8. str = "4321";
  9. }
  1. 1234
  2. 1234

# 参考

  1. JavaGuide:Java 为什么只有值传递?
  2. Java 到底是值传递还是引用传递? - Hollis的回答 - 知乎