形参和实参
- 形参(形式参数,Parameters):用于定义函数/方法,接收实参,不需要有确定值
- 实参(实际参数,Arguments):用于传递给函数/方法,必须要有确定值
public static void main(String[] args) {
// str为实参
String str = "Hello, World!";
sayHello(str);
}
// string为形参
static void sayHello(String string) {
System.out.println(string);
}
值传递和引用传递
- 值传递:方法接收的是实参值的拷贝,会创建副本
- 引用传递:方法接收的是实参所引用的对象在堆中的地址,不会创建副本,对于形参的修改将影响到实参
交换两个变量的值
@Test
public void testSwap1() {
int a = 10;
int b = 20;
System.out.println("a: " + a + ", b: " + b);
swap1(a, b);
System.out.println("a: " + a + ", b: " + b);
}
public void swap1(int a, int b) {
int temp = a;
a = b;
b = temp;
}
很明显这样子交换是不行的,传入的参数其实是实参的拷贝,所以并不会交换两个参数的值
正确的做法:
int A;
int B;
@Test
public void testSwap2() {
testStream t = new testStream();
t.A = 10;
t.B = 20;
System.out.println("A: " + t.A + ", B: " + t.B);
t.swap2(t);
System.out.println("A: " + t.A + ", B: " + t.B);
}
public void swap2(testStream t) {
int temp = t.A;
t.A = t.B;
t.B = temp;
}
往形参里面传入对量,在交换的时候就是实实在在的交换对象在堆中的地址,所以会发生交换
那
为什么Java只有值传递?
例1:传递基本类型参数
就是上面提到的交换两个参数值,在swap1()方法中,形参a,b二值进行交换并不会影响到实参a,b二值,只是实参复制的副本,无论副本怎么修改都不会影响到原件本身。
例2:传递引用参数类型(1)
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
System.out.println(arr[0]);
change(arr);
System.out.println(arr[0]);
}
public static void change(int[] array) {
array[0] = 0;
}
运行结果
1
0
其实这里传递的还是值,只不过这个值是实参的地址
也就是说change方法的参数拷贝的是arr(实参)的地址,因此他和arr指向的是同一个数组对象,这也就说明了为什么方法内部对形参的修改会影响到实参
例3:传递引用参数类型(2)
Person
package com.feliks;
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(String name) {
this.name = name;
}
}
public static void main(String[] args) {
Person xiaoZhang = new Person("小张");
Person xiaoLi = new Person("小李");
swap(xiaoZhang, xiaoLi);
System.out.println("xiaoZhang: " + xiaoZhang.getName());
System.out.println("xiaoLi: " + xiaoLi.getName());
}
public static void swap(Person person1, Person person2) {
Person temp = person1;
person1 = person2;
person2 = temp;
System.out.println("person1: " + person1.getName());
System.out.println("person2: " + person2.getName());
}
运行结果:
person1: 小李
person2: 小张
xiaoZhang: 小张
xiaoLi: 小李
可以看到,两个引用类型的形参交换并没有影响到实参,swap 方法的参数 person1 和 person2 只是拷贝的实参 xiaoZhang 和 xiaoLi 的地址。因此, person1 和 person2 的互换只是拷贝的两个地址的互换罢了,并不会影响到实参 xiaoZhang 和 xiaoLi