1.基本数据类型的传参机制
public class MethodParameter01{
public static void main(String[] args){
int a = 10;
int b = 20;
//创建A对象 名为obj
A obj = new A();
obj.swap(a,b); //调用swap
System.out.println("main方法a ="+ a + "b=" +b);
}
}
class A{
public void swap(int a, int b){
System.out.println("\na和b交换前的值\na ="+a+"\tb ="+b);
//完成a和b的交换
int temp = a;
a = b;
b = temp;
System.out.println("\na和b交换后的值\na = "+a+"\tb = "+b);
}
}
一个简单的值交换方法,但是底层逻辑还是值得说一说的,大家可以先想一下这三个out语句输出的是什么,然后来看一张内存图解释一下。
按照从上至下的语句执行顺序来看,创建main方法会在栈中创建一个main栈,依次定义a,b并初始化,创建A对象命名为obj。这时会在堆中产生一个obj对象。调用swap方法,调用方法时会在栈中产生一个新栈,为了简便我们称之为swap栈。
在swap方法中传入(a,b)两个形参。在swap方法里执行值交换的语句均是在swap栈中,这时,swap栈中a的值由10变为20,b的值由20变为10.故swap方法中的两个out语句输出的分别是值交换前后的a,b值(a=10,b=20和a=20,b=10),至此调用方法结束。
回到main方法中执行最后的out语句,那这里输出的a和b是交换前还是交换后的值呢?我们在内存中可以看到值交换的过程是swap栈中,结果返回到了main方法的方法调用语句,因此没有改变main方法中a,b的值,故输出为a=10,b=20
结论为:基本数据类型,传递的是值,形参的任何改变不影响实参
2.引用数据类型的传参机制
看这样一个案例:
B类中编写一个方法test1,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
public class MethodParameter01{
public static void main(String[] args){
B b = new B();
int[] arr = {1,2,3};
b.test1(arr); //调用方法
//遍历数组
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}
class B{
//B类中编写一个test1方法,接收一个数组,在方法中修改数组,看看原来的数组是否会变化
public void test1(int[] arr){
arr[0] = 100; //修改元素
// 遍历数组
System.out.println("test1的arr数组");
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}
先来看输出结果:
为什么这里的实参也变了呢?形参的改变不是不会影响实参吗?这是因为我们传入的形参为引用类型时,它传递的是地址,而不是具体一个参数的值。我们还是来看内存图。
创建main方法后,创建了一个B对象命名为b,即在堆中有一个B对象产生。随后定义一个数组,指向0x1122这个地址(举例用,实际过程中不一定指向这个地址)并进行初始化。
调用test1方法,传入形参(arr),即刻在栈中产生一个新栈,为简便我们称为test1栈,在test1方法中我们传入的arr同样指向0x1122的这个地址,修改数组元素时既是把这个地址上的元素改了。遍历时是修改后的数组。至此test1方法调用完毕。
回到main方法,继续执行语句,对数组进行遍历,这时遍历的数组依旧是0x1122这个地址上的数组,而它已经在test1方法中被就修改了元素。故而遍历结果是修改后的数组。
结论为:引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!
ps:引用类型和基本类型的传参机制大致就是这样,有些内容写的不是很好,若有疑惑可评论留言