首页IT科技java值传递和引用传递例子(死磕面试系列,Java到底是值传递还是引用传递?)

java值传递和引用传递例子(死磕面试系列,Java到底是值传递还是引用传递?)

时间2025-09-15 08:49:15分类IT科技浏览7570
导读:Java到底是值传递还是引用传递?...

Java到底是值传递还是引用传递?

这虽然是一个老生常谈的问题                ,但是对于没有深入研究过这块                        ,或者Java基础不牢的同学        ,还是很难回答得让人满意                。

可能很多同学能够很轻松的背出JVM                、分布式事务                        、高并发        、秒杀系统        、领域模型等高难度问题                ,但是对于Java基础问题不屑一顾                        。这种抓大放小的初衷是对的                        ,要是碰到深究基础细节的面试官        ,就抓瞎了        。

今天一灯带你一块深入剖析Java传递的底层原理        ,看完这篇文章再去面试                        ,面试官肯定要竖起大拇哥夸你:

“小伙子                ,你是懂Java传递的!                ”

1. 什么是形参和实参

形参: 就是形式参数        ,用于定义方法的时候使用的参数                        ,是用来接收调用者传递的参数的                。

实参: 就是实际参数                ,用于调用时传递给方法的参数                        。实参在传递给别的方法之前是要被预先赋值的        。

/** * @author 一灯架构 * @apiNote Java传递示例 **/ public class Demo { public static void main(String[] args) { String name = "一灯架构"; // 这里的name就是实际参数 update(name); System.out.println(name); } // 这里方法参数列表中name就是形式参数 private static void update(String name) { // doSomething } }

在Java方法调用的过程中,就是把实参传递给形参                        ,形参的作用域在方法内部        。

2. 什么是值传递和引用传递

值传递: 是指在调用方法时                        ,将实际参数拷贝一份传递给方法,这样在方法中修改形式参数时                ,不会影响到实际参数                        。

引用传递: 也叫地址传递                        ,是指在调用方法时        ,将实际参数的地址传递给方法                ,这样在方法中对形式参数的修改                        ,将影响到实际参数                。

也就是说值传递        ,传递的是副本        。引用传递        ,传递的是实际内存地址                        。这是两者的本质区别                        ,下面会用到                。

3. 测试验证

3.1 基本数据类型验证

先用基本数据类型验证一下:

/** * @author 一灯架构 * @apiNote Java传递示例 **/ public class Demo { public static void main(String[] args) { int count = 0; update(count); System.out.println("main方法中count:" + count); } private static void update(int count) { count++; System.out.println("update方法中count:" + count); } }

输出结果:

update方法中count:1 main方法中count:0

可以看到虽然update方法修改了形参count的值                ,但是main方法中实参count的值并没有变        ,但是为什么没有变?我们深究一下底层原理。

我们都知道Java基本数据类型是存储在虚拟机栈内存中                        ,栈中存放着栈帧                ,方法调用的过程,就是栈帧在栈中入栈                        、出栈的过程                        。

当执行main方法的时候                        ,就往虚拟机栈中压入一个栈帧                        ,栈帧中存储的局部变量信息是count=0                        。

当执行update方法的时候,再往虚拟机栈中压入一个栈帧                ,栈帧中存储的局部变量信息是count=0。

修改update栈帧中数据                        ,显然不会影响到main方法栈帧的数据                。

3.2 引用类型验证

再用引用类型数据验证一下:

/** * @author 一灯架构 * @apiNote Java传递示例 **/ public class Demo { public static void main(String[] args) { User user = new User(); user.setId(0); update(user); System.out.println("main方法中user:" + user); } private static void update(User user) { user = new User(); user.setId(1); System.out.println("update方法中user:" + user); } }

输出结果:

update方法中userUser(id=1) main方法中userUser(id=0)

由代码得知        ,update方法中重新初始化了user对象                ,并重新赋值                        ,并不影响main方法中实参数据                        。

当执行main方法时        ,会在堆内存中开辟一块内存        ,在栈内存中压入一个栈帧                        ,栈帧中存储一个引用                ,指向堆内存中的地址        。

当调用update方法时        ,会把main方法的栈帧拷贝一份                        ,再压入栈内存中                ,指向同一个堆内存地址                。

当执行update方法,重新初始化user对象                        ,并重新赋值的时候                        。会在堆内存中再开辟一块内存                        ,再把栈内存中update栈帧指向新的堆内存地址,并修改新的堆内存中的数据        。

从这里可以看出是值传递                ,修改了形参里面数据                        ,实参并没有跟着变化        。

3.3 同一地址的引用类型验证

/** * @author 一灯架构 * @apiNote Java传递示例 **/ public class Demo { public static void main(String[] args) { User user = new User(); user.setId(0); update(user); System.out.println("main方法中user:" + user); } private static void update(User user) { user.setId(1); System.out.println("update方法中user:" + user); } }

输出结果:

update方法中userUser(id=1) main方法中userUser(id=1)

可以看出update方法修改user对象的属性        ,main方法中user对象也跟着变了                        。

这是不是说明Java支持引用传递呢?

并不是                。这里在参数传递的过程中                ,只是把实参的地址拷贝了一份传递给形参                        ,update方法中只修改了参数地址里面的内容        ,并没有对形参本身进行修改        。

4. 总结

经过上述分析        ,Java参数传递中                        ,不管传递的是基本数据类型还是引用类型                ,都是值传递                        。

当传递基本数据类型        ,比如原始类型(int                、long        、char等)                        、包装类型(Integer                、Long、String等)                        ,实参和形参都是存储在不同的栈帧内                ,修改形参的栈帧数据,不会影响实参的数据                。

当传参的引用类型                        ,形参和实参指向同一个地址的时候                        ,修改形参地址的内容,会影响到实参。当形参和实参指向不同的地址的时候                ,修改形参地址的内容                        ,并不会影响到实参                        。

我是「一灯架构」        ,如果本文对你有帮助                ,欢迎各位小伙伴点赞                        、评论和关注                        ,感谢各位老铁        ,我们下期见

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
yolov5教程书籍PDF(yoloV5-face学习笔记) 三维目标的具体内容是什么(【三维目标检测】CenterPoint(一))