【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/ ...
随机推荐
- SQL SERVER 查询所有表 统计每张表的大小
(MySQL查看数据库表容量大小)[https://www.cnblogs.com/vipsoft/p/12145059.html] 查询某数据库中的所有数据表 SELECT name as tabl ...
- Java 项目工程搭建 --创建父工程
Java 项目工程搭建 --创建父工程 Java 项目工程搭建 --创建子模块(依赖父工程) Intellij 2018 更多详细内容见尚硅谷阳哥视频,实际项目中更多的是copy,修改pom Inte ...
- lab3 page tables
1.Speed up system calls (easy) 要求:有些操作系统(例如 Linux)通过在用户空间和内核之间的只读区域共享数据来加速某些系统调用.这样可以消除在执行这些系统调用时进行内 ...
- Educational Round 95 (Div. 2) A - B题题解(A题数据连错3次,搞人心态中)
1418A. Buying Torches 这次A题,真心fo了(导致wa了我两次) 样例出错两次,数据出错一次. 讲一下我的思路吧. 首先先明确至少需要多少个棍.\(k\) 个火炬,至少需要$k ∗ ...
- 第四届蓝桥杯(2013)C/C++大学A组省赛题解
第一题:高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯出生 ...
- windows 系统关闭占用端口的应用
开发中有时候开发工具把程序关闭了,但是后台并没有真正关闭程序,导致再次启动相同端口的程序时报端口已经被使用的错误,这时如何强制关闭已占用的端口 1.打开dos对话框 2.查找被占用的端口的进程号 ne ...
- uni-app实现扫码签到
1 uni.scanCode({ 2 success: res => { 3 this.$http({ 4 url: '/checkin/scanSign', 5 data: { 6 codeI ...
- [java] - 数据库连接工具类
package util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLExceptio ...
- SpringMVC07——Ajax
Ajax AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. AJA ...
- Shell-获取终端输入-read