Java中的值传递和地址传递(传值、传引用)
首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中。
更何况,要想知道Java到底是传值还是传引用,起码你要先知道传值和传引用的准确含义吧?可是如果你已经知道了这两个名字的准确含义,那么你自己就能判断Java到底是传值还是传引用。
这就好像用大学的名词来解释高中的题目,对于初学者根本没有任何意义。
一:搞清楚 基本类型 和 引用类型的不同之处
int num = 10;
String str = "hello";
<img src="https://pic2.zhimg.com/166032bc90958c21604110441ad03f45_b.jpg" data-rawwidth="728" data-rawheight="458" class="origin_image zh-lightbox-thumb" width="728" data-original="https://pic2.zhimg.com/166032bc90958c21604110441ad03f45_r.jpg">如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。
如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。
二:搞清楚赋值运算符(=)的作用
num = 20;
str = "java";
<img src="https://pic3.zhimg.com/287c0efbb179638cf4cf27cbfdf3e746_b.jpg" data-rawwidth="714" data-rawheight="572" class="origin_image zh-lightbox-thumb" width="714" data-original="https://pic3.zhimg.com/287c0efbb179638cf4cf27cbfdf3e746_r.jpg">对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。
如上图所示,"hello" 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)
三:调用方法时发生了什么?参数传递基本上就是赋值操作。
第一个例子:基本类型
void foo(int value) {
value = 100;
}
foo(num); // num 没有被改变
第二个例子:没有提供改变自身方法的引用类型
void foo(String text) {
text = "windows";
}
foo(str); // str 也没有被改变
第三个例子:提供了改变自身方法的引用类型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。
第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。
重点理解为什么,第三个例子和第四个例子结果不同?
下面是第三个例子的图解:
<img src="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_b.jpg" data-rawwidth="772" data-rawheight="398" class="origin_image zh-lightbox-thumb" width="772" data-original="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_r.jpg">builder.append("4")之后builder.append("4")之后
<img src="https://pic4.zhimg.com/ff2ede9c6c55568d42425561f25a0fd7_b.jpg" data-rawwidth="696" data-rawheight="424" class="origin_image zh-lightbox-thumb" width="696" data-original="https://pic4.zhimg.com/ff2ede9c6c55568d42425561f25a0fd7_r.jpg">下面是第四个例子的图解:下面是第四个例子的图解:
<img src="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_b.jpg" data-rawwidth="772" data-rawheight="398" class="origin_image zh-lightbox-thumb" width="772" data-original="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_r.jpg">
builder = new StringBuilder("ipad"); 之后
<img src="https://pic2.zhimg.com/46fa5f10cc135a3ca087dae35a5211bd_b.jpg" data-rawwidth="710" data-rawheight="438" class="origin_image zh-lightbox-thumb" width="710" data-original="https://pic2.zhimg.com/46fa5f10cc135a3ca087dae35a5211bd_r.jpg">
作者:Intopass
链接:https://www.zhihu.com/question/31203609/answer/50992895
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Java传递参数有两种方式:值传递和引用传递
值传递是传递数据:如基本数据类型都是值传递
引用传递是把形参和实参的指针指向了堆中的同一对象,对象的引用和数组的引用。
实参,Java的基本数据类型,如int,double等在函数的参数传递时,传递的是副本。String也属于这一范畴。
形参,而如果是对象,则传递的是引用。
作者:fbysss
msn:jameslastchina@hotmail.com
blog:blog.csdn.net/fbysss
声明:本文由fbysss原创,转载请注明出处
关键字:Java 传值 传引用
这是个老生常谈的问题了,引起过无数争论,但可以说一直没有一个令人满意的回答。
有些人非要故弄玄虚,把传引用说成是栈里面放的是引用的值,说只有传值没有传引用,那看看这句经典名言吧:
O'Reilly's Java in a Nutshell by David Flanagan (see Resources) puts it best: "Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'"
从这里也可以看到,David 也没那么生硬,不过是看你从哪个角度来认识这个问题,如果大家习惯c++的那种传参时的理解方式,为何不能这么比较呢?
有人已经总结过:
参见
http://www.javaresearch.org/article/3156.htm
1、对象是按引用传递的
2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
写的没错,但是文字太多,第二条就已经把人弄糊涂了,得仔细看完4条才清楚。而且对String类型的疑惑没有解决。
这么简单的事情,何必这么绕呢?为啥没人跟c++过不去,偏要跟Java来劲?
三句话总结一下:
1.对象就是传引用
2.原始类型就是传值
3.String等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。
其他参考文章:
http://www-128.ibm.com/developerworks/cn/java/l-jpointer/index.html
http://dreamhead.blogbus.com/logs/2005/05/1189478.html
http://www.javaeye.com/topic/12961
Java中的值传递和地址传递(传值、传引用)的更多相关文章
- Java中不得不谈的值传递和地址传递
个人的一些认识,希望能对初学Java的你,或者困惑于方法参数传递的你祈祷一丝帮助! 下面是一些作者的个人观点,如果有错,欢迎各位大牛指出错误,灰常感谢您的观看与支持... -------------- ...
- Java中的值传递
1.先比较下字符串的比较 == 代表全等于 值和地址(存放地址) 全部相等于. equals 值等于== 和 equals的区别 列如下面的 如果name1==name2是等于的 然而name1==n ...
- 为什么说Java中只有值传递
本文转载自公众号 Hollis 对于初学者来说,要想把这个问题回答正确,是比较难的.在第二天整理答案的时候,我发现我竟然无法通过简单的语言把这个事情描述的很容易理解,遗憾的是,我也没有在网上找到哪篇文 ...
- 一道笔试题来理顺Java中的值传递和引用传递
题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...
- java中的值传递和引用传递有什么区别呀?
值传递: (形式参数类型是基本数据类型和String):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参 ...
- 为什么说Java中只有值传递(转载)
出处:https://www.hollischuang.com/archives/2275 关于这个问题,在StackOverflow上也引发过广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同, ...
- 为什么说Java中只有值传递?
一.为什么说Java中只有值传递? 对于java中的参数传递方式中是否有引用传递这个话题,很多的人都认为Java中有引用传递,但是我个人的看法是,Java中只有值传递,没有引用传递. 那么关于对象的传 ...
- JAVA中只有值传递
今天,我在一本面试书上看到了关于java的一个参数传递的问题: 写道 java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? 我毫无疑问的回答:“引用传递!”,并且还觉得自己对java的这 ...
- 为什么说Java中只有值传递----说服自己
在开始深入讲解之前,有必要纠正一下大家以前的那些错误看法了.如果你有以下想法,那么你有必要好好阅读本文. 错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递.如果是个引用,就 ...
随机推荐
- 解决Visual C++工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)的办法
2014-01-17 23:36 5128人阅读 评论(1) 收藏 举报 分类: 资料集(282) 版权声明:本文为博主原创文章,未经博主允许不得转载. 之前使用网上的一个开源代码,被封装成Windo ...
- TextView 垂直居中
需要区分的是这里的top,bottom,ascent,descent,baseline是指字内容的属性,通过getPaint().getFontMetricsInt()来获取得到.和字体内容的外部容 ...
- 对于nginx为什么能提高性能
对于后端是动态服务来说,比如Java和PHP.这类服务器(如JBoss和PHP-FPM)的IO处理能力往往不高.Nginx有个好处是它会把Request在读取完整之前buffer住,这样交给后端的就是 ...
- RzToolbutton用法
- delphi Form显示先后问题
- MyBatis 一级缓存避坑
MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选: package org.apache.ibatis.session; /** * @autho ...
- MFC学习(三):项目学习
1. 概述 MFC程序由CWinApp.MainFrm(含Menu,可用CSplitterWndEx分割).众多Dialog等组成. MFC既可以使用纯Dialog的形式,也可以使用Document+ ...
- 【QTP专题】连接数据库
获取数据库连接串 在本地新建一个.txt文件,修改扩展名名*.udl:双击*.udl文件,打开数据库链接属性,定位到"提供程序"选显卡,选中如sqlserver的连接 Micro ...
- [HAOI2010]计数(组合数学)(数位DP)
原题题意也就是给的数的全排列小于原数的个数. 我们可以很容易的想到重复元素的排列个数的公式. 但是我们发现阶乘的话很快就会爆long long啊(如果您想写高精请便) 之后我就尝试质因数分解....但 ...
- VSM Import Cluster功能验证二(导入篇)
三 vsm import cluster 3.1登录vsm web UI 登陆 VSM web UI,https://172.16.34.51/dashboard/vsm/,点击Cluster Man ...