用户名
Email
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
帖子
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
后端开发
›
Java
›
【Java】引用传递?值传递?
【Java】引用传递?值传递?
反转基因福娃
金牌会员
|
2023-5-22 15:40:42
|
显示全部楼层
|
阅读模式
楼主
主题
939
|
帖子
939
|
积分
2817
引用传递和值传递,从上学那会儿就开始强调的概念,不管你是计算机相关专业还是自学Java,一定听过这么一句话:
方法调用参数如果是对象,那就是引用传递,如果是基本数据类型,就是值传递。
比如:function(Object o)就是引用传递,function(int i)就是值传递。这两个概念似乎很好理解,我们只需要记住对象和基本数据类型的区别就行了。但是,真的是这样吗?
有一段代码如下:
public static void main(String[] args) {
int i = 0;
System.out.println(i);
change(i);
System.out.println(i);
}
private static void change(int i) {
i = 1;
}
复制代码
输出结果比较好猜测,也应该都能答对:
0
0
复制代码
下一个问题,如果将int改成String呢?
public static void main(String[] args) {
String s = "0";
System.out.println(s);
change(s);
System.out.println(s);
}
private static void change(String s) {
s = "1";
}
复制代码
输出的结果如下:
0
0
复制代码
嗯?有疑问了吧?不是引用传递吗?我在方法里命名修改了s的值,为什么输出还是”0“呢?难度String作为Object有什么特殊性?
别急,继续看下一段代码:
public static void main(String[] args) {
Person p = new Person("0");
System.out.println(p);
change(p);
System.out.println(p);
}
private static void change(Person p) {
p = new Person("1");
}
static class Person{
String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
复制代码
结果会输出什么?
Person{name='0'}
Person{name='0'}
复制代码
看来String和其他Object没什么不同,可是这样的结果好像不太符合我们对引用传递的认知啊。其实我感觉这两个概念没有必要区分,实质是一回事,都是将栈中引用复制了一份传递到方法中,无论在方法中如何对引用操作,都是操作的副本,只是对于基本数据类型来说,值存储在栈中,引用存储的就是值,而对象来说,引用中存储的是对象在堆中的内存地址,参数传递时生成的副本仍然指向了原来引用指向的对象,所以如果直接操作该对象是有效的。简单画个图方便理解:
[img]https://img2023.cnblogs.com/blog/3076343/202305/3076343-202305221340
05869-15804904.png[/img]
如果对p的操作不是将该引用指向一个新的值,而是对p指向的对象进行操作,就能看到所谓引用传递的效果了例如:
public static void main(String[] args) {
Person p = new Person("0");
System.out.println(p);
change(p);
System.out.println(p);
}
private static void change(Person p) {
p.name = "1";
}
static class Person{
String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
复制代码
此时,执行结果为:
Person{name='0'}
Person{name='1'}
复制代码
总结:
Java进行方法调用时参数传递是将栈中的引用复制了一份到该方法的工作区,如果引用指向了一个堆中的对象,那么副本也指向这个对象。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
反转基因福娃
金牌会员
这个人很懒什么都没写!
楼主热帖
设计模式---组合模式
【Unity3D】Transform组件
Spark快速上手(4)Spark核心编程-Spark ...
拿到12家offer,想给大家分享一下面试 ...
【渗透攻击】PowerShell与Shell 有什么 ...
echarts使用及遇到的问题
如何将鸿蒙(harmonyOS)系统退回安卓 ...
写了这么久Java项目,是否还记得你的第 ...
[工具使用]SqlMap
软件工程经济学第一章
标签云
存储
服务器
快速回复
返回顶部
返回列表