21--方法参数的值传递机制

方法,必须由其所在类或对象调用才有意义。参数的方法,参数分为形参和实参:
形参:方法声明时的参数。
实参:方法调用时实际传给形参的参数
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本 (复制品)传入方法内(in模式),而参数本身不受影响。
在java中根据数据类型划分,参数又可以分为基本数据类型参数和引用数据类型参数。
形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参 。
形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参。

基本数据类型的参数传递

实例:

package com.qwy;
/**
 * 基本数据类型的参数值传递
 * @author qwy
 *
 */
public class ValueTransferTest {
    
    
	public static void main(String[] args) {
    
    
		int num = 3;
		System.out.println("调用change()方法之前的num的值:"+num);//3
		change(num);
		System.out.println("调用change()方法之后的num的值:"+num);//3
	}
	public static void change(int num){
    
    
		System.out.println("change()修改之前的num的值:"+num);//3
		num = 5;
		System.out.println("change()修改之后的num的值:"+num);// 5
	}
}

执行结果:
调用change()方法之前的num的值:3
change()修改之前的num的值:3
change()修改之后的num的值:5
调用change()方法之后的num的值:3

前三个输出结果基本没有任何异议,第四个结果为什么打印的是3而不是5呢?这里需要从内存角度来思考:

  1. 首先我要确定定义在方法中的变量为局部变量,局部变量存放位置为栈内存。
  2. 当main方法执行到int num = 3时 ,在栈内存中存储了变量 num且值为3.所以紧接着输出的num变量的值为3,好理解
  3. 当在main方法中执行到change(num)时,此时num作为实参传入change()方法,且此时num的值为3 ,也就是change(3).
  4. 此时开始执行change方法,在change(int num)方法中参数num作为形参接收上一步的3,而此时的num参数有作为change方法的局部变量,所以此时站内存中也会存在change的一个局部变量num ,且值为3,所以change方法的第一打印输出3.
  5. 紧接着在change方法中给局部变量重新赋值 num = 5,所以紧跟的输出语句输出5.
  6. 此时change()方法执行完毕,又回到了main方法中。此时change方法中的局部变量num,由于方法执行完毕,所以num失效(此时num出栈),但是main方法还没有执行完毕,也就是main方法存储在栈中的num变量还没有失效,值依然是3.所以此时输出3也就好理解了。
    示意图:
    在这里插入图片描述
    在这里插入图片描述

引用数据类型的参数传递

实例:
Data类:

package com.qwy;

public class Data {
    
    
	int num;
}	

ValueTransferTest2类:

package com.qwy;
/**
 * 基本数据类型的参数值传递
 * @author qwy
 *
 */
public class ValueTransferTest2 {
    
    
	public static void main(String[] args) {
    
    
		Data obj= new Data();
		obj.num=3;
		System.out.println("调用change()方法之前的num的值:"+obj.num);//3
		change(obj);
		System.out.println("调用change()方法之后的num的值:"+obj.num);//5
	}
	public static void change(Data obj){
    
    
		System.out.println("change()修改之前的num的值:"+obj.num);//3
		obj.num = 5;
		System.out.println("change()修改之后的num的值:"+obj.num);// 5
	}
}


运行结果:
调用change()方法之前的num的值:3
change()修改之前的num的值:3
change()修改之后的num的值:5
调用change()方法之后的num的值:5

从打印结果看,引用数据类型跟基本数据类型传值不同。就这个例子来看:

  1. 首先要知道引用数据类型的属性(成员变量)值存储在堆内存中。
  2. 当main方法执行Data ojb= new Data();开辟堆内存0x3000,并将该地址赋值给变量ojb.
  3. 执行obj.num=3;后堆内存存储的是3.所以此时打印obj.num的值为3.
  4. 执行到change(obj)时,将ojb的地址传递给change(Data obj)方法。此时虽然obj作为change方法的局部变量,但是此时ojb保存的是obj的地址,跟main方法创建的ojb是同一个实例,指向同一个堆内存块。所以change方法第一个打印语句仍然输出3.
  5. 当程序执行到了change方法的obj.num = 5时,因为main方法和change方法的ojb都指向同一个堆内存地址。所以此时堆内存存在了变量值为5.change方法自然此时再打印便打印5.
  6. change方法运行完毕,但是堆内存中仍然存在main方法的引用,此时main调用obj.num,自然是被change方法修改过的(change方法和main方法操作的是同一个对象),所以此时调用obj.num,也就输出5.

图示:
在这里插入图片描述
====================================================================================================
  自己也是最近才开始写文章,看到大家都分享自己的经验给别人。我也是受益者之一,做人不能只懂的索取而不去回馈,所以也将自己学习的知识分享给大家。我不能保证每个问题都讲的是对的,毕竟我也是个学习者。如果有地方写得不对或理解有误的,也希望大家给指出,我当非常感谢。编写过程也不易,也希望大家给个赞,关注下本人。这也能激励我继续分享。
  ====================================================================================================

猜你喜欢

转载自blog.csdn.net/qwy715229258163/article/details/114296118
今日推荐