【Java】引用传递?值传递?
引用传递和值传递,从上学那会儿就开始强调的概念,不管你是计算机相关专业还是自学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没什么不同,可是这样的结果好像不太符合我们对引用传递的认知啊。其实我感觉这两个概念没有必要区分,实质是一回事,都是将栈中引用复制了一份传递到方法中,无论在方法中如何对引用操作,都是操作的副本,只是对于基本数据类型来说,值存储在栈中,引用存储的就是值,而对象来说,引用中存储的是对象在堆中的内存地址,参数传递时生成的副本仍然指向了原来引用指向的对象,所以如果直接操作该对象是有效的。简单画个图方便理解:

如果对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进行方法调用时参数传递是将栈中的引用复制了一份到该方法的工作区,如果引用指向了一个堆中的对象,那么副本也指向这个对象。
【Java】引用传递?值传递?的更多相关文章
- Java中的值传递和引用传递
这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...
- 一道笔试题来理顺Java中的值传递和引用传递
题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...
- java中的值传递和引用传递有什么区别呀?
值传递: (形式参数类型是基本数据类型和String):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参 ...
- 理解--->Java中的值传递&引用传递
转自:http://url.cn/5tL9F5D 值传递和引用传递 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际 ...
- Java 中的值传递和引用传递问题
Java 中的值传递和引用传递问题 public class Operation { int data = 50; void change(int data) { data = data + 100; ...
- Java中的值传递和地址传递(传值、传引用)
首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中.更何况,要想知道 ...
- Java中的值传递与“引用传递”
首先,Java没有 引用传递 这么一说. Java仅仅有值传递.传递的都是值,基本数据类型传递的是值.引用类型传递的是地址值. 我来理一下这当中宛如米线跟米面绞在一起了,再跟粉丝混在一起的关系. 好的 ...
- Java中只有值传递,(及值传递与引用传递详解)
首先呢,我们来说一下值传递与引用传递的区别(这两个玩意儿实在调用函数的时候提到的) 比如说 code( a) code( int a ) code(a)是调用函数,a是我们原本函数的一个值类型,然后使 ...
- 188W+程序员关注过的问题:Java到底是值传递还是引用传递?
在逛 Stack Overflow 的时候,发现了一些访问量像阿尔卑斯山一样高的问题,比如说这个:Java 到底是值传递还是引用传递?访问量足足有 188万+,这不得了啊!说明有很多很多的程序员被这个 ...
- java都是值传递,没有引用传递
博主这几天在复习 javaSE 部分的内容时,遇到了关于参数传值的问题,但是始终不知道原因,上网上一查才知道钻牛角尖了,把C语言的参数传值转移到java中了. 相信很多在学习java之前,有接触过C/ ...
随机推荐
- 面试官:分库分表后如何生成全局ID?
分库分表后就不能使用自增 ID 来作为表的主键了,因为数据库自增 ID 只适用于单机环境,但如果是分布式环境,是将数据库进行分库.分表或数据库分片等操作时,那么数据库自增 ID 就会生成重复 ID,从 ...
- 同步时间,为什么我选 Chrony 而不是 NTP ?
初识 chrony chrony 是网络时间协议(Network Time Protocol )的通用实现 它不但可以提供保持系统时间与 NTP 时钟服务器同步的服务,还能作为 NTP 服务器对其他服 ...
- @Scheduled cron 定时任务表达式含义,及* ?的区别
好多网友对@Scheduled cron表达式含义做了阐述,个人认为很多对于 * ?的说明不够具体也不算准确,借此本文特别对 * ?做一下说明. cron格式:[秒数][分钟][小时][日期][月份] ...
- 2017年第八届 蓝桥杯C组 C/C++决赛题解
蓝桥杯历年国赛真题汇总:Here 1.哥德巴赫分解 哥德巴赫猜想认为:不小于4的偶数都可以表示为两个素数的和. 你不需要去证明这个定理,但可以通过计算机对有限数量的偶数进行分解,验证是否可行. 实际上 ...
- 蓝桥杯历年省赛试题汇总 C/C++ A组
A组 省赛 B 组的题目可以在这里查看 → 刷题笔记: 蓝桥杯 题目提交网站:Here 2013 第四届 高斯日记 排它平方数 振兴中华 颠倒的价牌 前缀判断 逆波兰表达式 错误票据 买不到的数目 剪 ...
- ==和equals的区别和联系,StringBuffer和StringBuilder,clone方法
==和equals的区别和联系? ( 1)对于==,比较的是值是否相等 如果作用于基本数据类型的变量,则直接比较其存储的 "值"是否相等: 如果作用于引用类型的变量,则比较的是所指 ...
- mock.js使用
前后端联调必备技术之Mock讲解 什么是Mock数据? 处于开发环境模拟接口返回的数据(用于开发状态后端还没给接口) 不会影响生产环境,只是方便我们还没与后端交互时,不阻塞我们开发流程 mock数据好 ...
- hdu 5234
题意:求在不超过k的情况下,最多可以得到多少价值. 三维dp,结合01背包,第三维就是用来保存在不同的背包容量下能得到的最大价值,也就是第三维有很多状态. #include<iostream&g ...
- javaweb 项目!号 解决方案
1:右击项目工程名称2:Properties3: Jvav Build Path4: Libraries5: Add External JARS6: 找到"E:\apache-tom ...
- 持续集成指南:Gitlab CI/CD 自动部署前端项目
前言 之前陆续写了 Gitlab 的安装使用还有 Gitlab CI/CD 的配置使用,已经把 AspNetCore 的后端项目都做了持续集成了,尝到甜头之后,现在前端的项目也要加入自动化部署,所以经 ...