一、基本概念
理论基础点击java核心技术—参数传递
参数类型
- 形参: 方法被调用时需要传递进来的参数,例如:function(int a)中的a,他只有func被调用期间a才有意义,也就是被分配内存空间,在方法function方法被执行完后,a就会被销毁释放内存空间,也就不存在了
- 实参: 方法被调用时传递进来的实际值,他在方法被调用前就已经被初始化,并且在方法被调用时传入。 值传递和引用传递
- 值传递:
在方法被调用时,实参通过把他的内容副本传入方法内部,此时形参接收的内容是实参的一个拷贝,因此在方法内对实参的任何操作,都仅仅是对这个内容的副本进行操作,不影响原初始值的内容。值传递传递的是一个真实内容的副本,对副本的操作不影响原内容,也就是形参怎么变化,不影响实参对应的内容。 - 引用传递:
"引用”也就是指向真实内容的地址值。在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向同一块内存地址,对形参的操作会影响原来的内容。
二、代码实现
先来看个例子:
package com.mystep.step;
import com.mystep.step.entity.Student;
/**
* @author step
* @date 2021年08月12日 0:59
*/
public class demo01 {
public static void main(String[] args) {
Student a=new Student();
Student b=new Student();
a.setName("张三");
b.setName("李四");
swap1(a,b);
System.out.println("swap1方法执行后的-------a:"+a);
System.out.println("swap1方法执行后的-------b:"+b);
swap2(a,b);
System.out.println("swap2方法执行后的-------a:"+a);
System.out.println("swap2方法执行后的-------b:"+b);
int c=10;
int d=20;
Integer e=10;
Integer f=20;
swap3(c,d);
System.out.println("swap3方法执行后的------c:"+c);
System.out.println("swap3方法执行后的------d:"+d);
swap4(e,f);
System.out.println("swap4方法执行后的------e:"+e);
System.out.println("swap4方法执行后的------f:"+f);
}
private static void swap1(Student e,Student f){
System.out.println("传入的e:"+e);
System.out.println("传入的f:"+f);
String name=e.getName();
e.setName(f.getName());
f.setName(name);
System.out.println("修改后的e:"+e);
System.out.println("修改后的f:"+f);
}
private static void swap2(Student e,Student f){
System.out.println("传入的e:"+e);
System.out.println("传入的f:"+f);
Student a=e;
e=f;
f=a;
System.out.println("修改后的e:"+e);
System.out.println("修改后的f:"+f);
}
private static void swap3(int a,int b){
System.out.println("传入的a:"+a);
System.out.println("传入的b:"+b);
int c=a;
a=b;
b=c;
System.out.println("修改后的a:"+a);
System.out.println("修改后的b:"+b);
}
private static void swap4(Integer a,Integer b){
System.out.println("传入的a:"+a);
System.out.println("传入的b:"+b);
Integer c=a;
a=b;
b=c;
System.out.println("修改后的a:"+a);
System.out.println("修改后的b:"+b);
}
}
执行结果
三、原理分析(栈和堆内的情况)
我们通过栈和堆来仔细 研究一下这个原因
程序刚开始,栈中进入a,b, 堆中有个指定的对象
接下来我们调用了swap1方法
因为调用了新的方法,所以我们引入了新的栈帧,同样指向堆里的同一位置,因为方法里面有name属性,同样引入
swap1执行
e.setName(f.getName());
f.setName(name);
数值交换
程序执行完,方法里的出栈,销毁
我们可以看到,a,b,指向的值变化了
swap2方法
执行方法时
执行完,同样销毁,对于a和b的影响没有
swap3
因为c,d 是一个整形值,直接在栈内进行分配
这个方法里面的整体操作是对传入的int a,int b 进行操作,不影响原来的 a ,b
swap 4 同理