方法的参数传递机制
创建好一个方法,肯定是需要使用的,也就是调用方法是怎么调用的
而方法是依靠类(当是static修饰的方法)或者是对象(普通方法)来作为调用者
方法的参数分实参于形参
当定义方法时候,方法包含了参数,此时这个参数叫做形参
当使用方法时候,要根据定义方法的参数来传入参数,此时这个参数被称为形参
问:java的实参是怎么传入方法的
答:依靠方法的参数传递机制来控制,java方法的参数传递只有值传递一种
值传递就是把实参复制出一个副本,把副本传入方法,而实参却不会受到任何影响
public class Test1 {
public static void change (int a,int b){
int temp = a;
a = b;
b = temp;
System.out.println("使用change方法后现在a b的值:a="+a +"," +"b="+b);
}
public static void main(String[] args) {
int a = 2;
int b = 3;
change(a,b);
System.out.println("注意看main方法的值没有任何改变"+"a="+a+","+"b="+b);
}
}
change方法里面的a、b值是2、3,交换后,a、b值是3、2
而main方法里面的a、b还是2、3
所以change方法里面的a、b只是main方法里面a、b的复制品
当程序执行change方法时候,将main方法中的a、b复制一份作为复制品作为参数值传入change,所以,此时change方法里面的a、b不是a、b本身
在main方法中调用change方法,因为main方法还没结束,所以,此时系统会分配这两个方法的栈区
执行change方法交换a、b的值,只是对change方法里面的a、b交换
交换后输出change中a、b的值,而main方法中a、b并没有交换
这就是值传递
当系统开始执行方法时,系统为形参执行初始化,就是把实参变量的值赋给方法的形参变量,方法里操作的并不是实际的实参变量
当然,对于引用类型的参数传递也是采用的值传递,只不过有点特殊
class Test{
int a;
int b;
}
public class Test1 {
public static void change (Test ch){
int temp = ch.a;
ch.a = ch.b;//9
ch.b = temp;//6
System.out.println("使用change方法后现在a b的值:a="+ch.a +"," +"b="+ch.b);
}
public static void main(String[] args) {
Test test = new Test();
test.a = 6;
test.b = 9;
change(test);
System.out.println("交换后"+"a="+test.a+","+"b="+test.b);
}
}
change方法里面的a、b两个都被交换成功,并且main方法里面的a、b值也发生了交换
最开始main方法执行创建了Test对象,并且定义了test引用变量来指向Test对象,
创建一个对象,系统内存当中有
1、堆内存中保存了对象本身
2、栈内存中保存了引用对象的引用变量
对象创建好就给他们赋值,此时a、b为6、9
main方法调用change方法,因为main还没有执行结束,系统会分配main、change两个栈区,用于存放这两个方法中各自的局部变量
调用change方法,test变量作为实参传入change方法,也是采用值传递
把main方法的test变量的值赋值给change方法中test的形参,也就是完成change方法中test形参1的初始化
main方法中test是一个引用(也就是指针),它保存了Test对象的内存地址
当test的值赋值给change方法的test形参后,同样让change方法的test形参也保存了这个内存地址
所以也会引用到堆内存中的Test对象
虽然也是值传递,将test的副本传入了change方法
但是关键在于test只是一个引用变量,引用变量里面保存的是内存地址
因为内存地址相同,两个方法都是引用的同一个对象,所以当其中一个方法进行改变,另外一个方法也跟着改变
基本类型与引用类型都是拷贝的值,只不过,基本类型自己把值拷贝了(保存的是的值),引用类型拷贝的是内存地址(保存的是内存地址)
如果说,在change方法的最后一行增加
public static void change (Test ch){
int temp = ch.a;
ch.a = ch.b;
ch.b = temp;
System.out.println("使用change方法后现在a b的值:a="+ch.a +"," +"b="+ch.b);
// ch 直接赋值为 null ,让它不再指向任何有效地址
ch = null ;
}
注意:赋值为null表示与堆内存对象的联系断了,并不是指把对象赋值null,只是让它不再指向任何有效地址
所以,在这里,只是change方法中失去了Test的引用,它不在访问堆内存中的Test对象,
但是main方法中的变量却不受影响,所以可以输出a、b的值