为什么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;
}
}
- 上面代码块执行的某一步,堆和栈的状态:
流程如下:
- 首先入口函数main()被加载到栈内存中,顺序执行main()中的语句;
- 栈中开辟了一块内存,存储" int number = 100";
- 执行输出,输出number=100;
- 调用 change(), 同样这个方法也会被加载到栈内存中;
- 程序此时进入change()内部,加载形参"int number"存放在栈中,由于实参为100,所以此时栈中为"int number = 100" ;
- 在执行change()的" number =200"后, 此时栈中change()的参数变为" int number =200";
- change()内语句全部执行完毕,从栈中消失;
- 回到main()内,输出number的值,显而易见 number仍旧是100;
- 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;
}
}
流程如下:
-
首先入口函数main()被加载到栈内存中,顺序执行main()中的语句;
-
由于数组是引用数据类型,所以
栈中开辟一块内存,存储arr数组变量名(即等号左边的 int[] arr), 以及数组具体值在堆内存中的位置001
; -
在声明数组(开辟栈空间)同时,我们给数组赋值(对数组进行初始化),此时
堆中开辟地址存储这个数组的具体数据
(即等号右边的数组值);
-
接着执行输出函数,输出arr[1];
-
继续执行,调用chage()函数, 这个函数被加载到栈中, 并且栈中有形参 int[] arr, 由于main()中给传入了实参arr(其实传的就是引用,也就是堆中arr具体数据的内存地址),所以
在栈中的change()内,int[] arr 的值(堆的内存地址)也为001
.
-
顺序执行change()方法中的语句,我们根据栈中存储的
arr[]数组具体数据在堆中的地址
,找到arr[1],并把它改为200;
-
chang()方法执行完毕后从栈中消失,接着执行第二次输出;
-
main()执行完毕.从栈中消失.
二, 总结:
- Java是值传递的.
2.1, 基本类型的数据
- 对于基本数据类型的数据,由于其变量和值都存储在栈空间中, 所以在这个变量作为实参被传递时, 接收这个变量的其他变量(形参)在他所在的栈空间会持有一份这个变量值的拷贝, 所以其他变量(形参)对这个值的改变仅限于在自己的栈空间中,影响不到源数据的噢!
2.2, 引用类型的数据
- 对于引用数据类型的数据,其变量声明,变量名(等号左边的内容)都存放在栈空间中,而具体的数据(比如数组的值)都保存在堆空间中, 为了能顺利访问到数据,我们还会在栈空间中存储堆中对应数据的内存地址(toString()方法可以看到噢,格式为 变量名@内存地址) 之所以叫引用数据类型,原因就在于此.
- 所以当这个变量(实参)被其他变量(形参)接收之后,其他变量(形参)也会有一个与之相同的到堆中数据的内存地址, 这个变量和其他变量都可以直接的修改数据.
终极结论
java中方法参数传递方式是按值传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)