为什么Java是值传递的? 1

一, 前置知识:

1. 形参和实参

  • 形参: 方法定义中的参数, 等同于变量定义格式,由数据类型和变量名组成.
  • 实参: 方法调用中的参数 , 等同于使用变量或常量., 不带数据类型和变量名,要么是个常量值,要么是个变量名

1.1. 方法参数传递(基本类型)

对于基本数据类型的参数,形式参数的改变,不影响实际参数的值.

示例代码:

public class ArgsDemo01{
	public static void main(String[] args){
		int number = 100;
		System.out.println("调用change方法前:"+ number);
		change(number);
		System.out.println("调用change方法后:"+ number);
	}
	public static void change(int number){
		number = 200;
	}
}
  • 上面代码块执行的某一步,堆和栈的状态:

在这里插入图片描述

流程如下:

  1. 首先入口函数main()被加载到栈内存中,顺序执行main()中的语句;
  2. 栈中开辟了一块内存,存储" int number = 100";
  3. 执行输出,输出number=100;
  4. 调用 change(), 同样这个方法也会被加载到栈内存中;
  5. 程序此时进入change()内部,加载形参"int number"存放在栈中,由于实参为100,所以此时栈中为"int number = 100" ;
  6. 在执行change()的" number =200"后, 此时栈中change()的参数变为" int number =200";
  7. change()内语句全部执行完毕,从栈中消失;
  8. 回到main()内,输出number的值,显而易见 number仍旧是100;
  9. main()执行完毕.从栈中消失.

1.2. 方法参数传递(引用类型)

对于引用类型的参数,形式参数的改变,影响实际参数的值.

  • 示例代码:
public static void main(String[] args){
	public static void main(String[] args){
		int[] arr = {10,20,30};
		System.out.println("调用change方法前:"+ arr[1]);
		change(arr);
		System.out.println("调用change方法前:"+ arr[1]);
	}
	public static void change(int[] arr){
		arr[1] = 200;
	}
}

流程如下:

  1. 首先入口函数main()被加载到栈内存中,顺序执行main()中的语句;

  2. 由于数组是引用数据类型,所以栈中开辟一块内存,存储arr数组变量名(即等号左边的 int[] arr), 以及数组具体值在堆内存中的位置001;

  3. 在声明数组(开辟栈空间)同时,我们给数组赋值(对数组进行初始化),此时堆中开辟地址存储这个数组的具体数据(即等号右边的数组值);
    在这里插入图片描述

  4. 接着执行输出函数,输出arr[1];
    在这里插入图片描述

  5. 继续执行,调用chage()函数, 这个函数被加载到栈中, 并且栈中有形参 int[] arr, 由于main()中给传入了实参arr(其实传的就是引用,也就是堆中arr具体数据的内存地址),所以在栈中的change()内,int[] arr 的值(堆的内存地址)也为001.
    在这里插入图片描述

  6. 顺序执行change()方法中的语句,我们根据栈中存储的arr[]数组具体数据在堆中的地址,找到arr[1],并把它改为200;
    在这里插入图片描述

  7. chang()方法执行完毕后从栈中消失,接着执行第二次输出;
    在这里插入图片描述

  8. main()执行完毕.从栈中消失.

二, 总结:

  • Java是值传递的.
2.1, 基本类型的数据
  • 对于基本数据类型的数据,由于其变量和值都存储在栈空间中, 所以在这个变量作为实参被传递时, 接收这个变量的其他变量(形参)在他所在的栈空间会持有一份这个变量值的拷贝, 所以其他变量(形参)对这个值的改变仅限于在自己的栈空间中,影响不到源数据的噢!
2.2, 引用类型的数据
  • 对于引用数据类型的数据,其变量声明,变量名(等号左边的内容)都存放在栈空间中,而具体的数据(比如数组的值)都保存在堆空间中, 为了能顺利访问到数据,我们还会在栈空间中存储堆中对应数据的内存地址(toString()方法可以看到噢,格式为 变量名@内存地址) 之所以叫引用数据类型,原因就在于此.
  • 所以当这个变量(实参)被其他变量(形参)接收之后,其他变量(形参)也会有一个与之相同的到堆中数据的内存地址, 这个变量和其他变量都可以直接的修改数据.
终极结论

java中方法参数传递方式是按值传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。

1, 对于值传递,更详细的解读
2,文中程序的视频详细解读(p83, p84)

posted @   青松城  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示