`

不纠结!Java是按值传递的!

阅读更多
在Java中,所有的方法参数,都是"按值传递".
有那么一种说法,Java中基本类型是按值传递,对象是按引用传递.这个说法其实是不确切的,确切的说法是
Java中基本类型将值作为参数,按值传递.对象将引用作为参数,按值传递.
所谓按值传递,就是传递的是一个副本.对象引用的副本,也算是按值传递!

现在来解释下Java方法传递引用时的情况.
比如说有一个引用 A a = new A();
将a当作参数传递的时候,传递的不是a指向的对象,也不是a引用本身,而是a的一个副本,并且这个副本和a是一模一样.  这里的一模一样就是a和副本指向同一个对象.
那么当a的副本进入方法后,对这个副本的修改同样会影响a.
但是如果进入方法后将a的副本指向其它对象的时候,那么和a是一点关系都没有了.

看一段代码和运行结果:
public class A {
	int a = 0;
}

public class Test {

	public static void main(String[] args) {
		A a = new A();
		A a2 = new A();
		System.out.println("改变前的a:" + a);
		System.out.println("改变前的a2:" + a2);
		System.out.println("-----------------");
		doSomething(a, a2);
		System.out.println("-----------------");
		System.out.println("改变后的a:" + a);
		System.out.println("改变后的a2:" + a2);
		System.out.println("-----------------");
		System.out.println(a.a);
		System.out.println(a2.a);
	}

	public static void doSomething(A a, A a2) {
		System.out.println("方法内前的a:" + a);
		a.a = 2;
		a = a2;
		System.out.println("-----------------");
		System.out.println("方法内的a:" + a);
		System.out.println("方法内的a2:" + a2);
	}
}


结果:
①改变前的a:A@18a992f
②改变前的a2:A@4f1d0d
-----------------
③方法内前的a:A@18a992f  
-----------------
④方法内的a:A@4f1d0d
⑤方法内的a2:A@4f1d0d
-----------------
⑥改变后的a:A@18a992f
⑦改变后的a2:A@4f1d0d
-----------------
⑧2
⑨0


解释:

③说明,方法内的a为方法外a的一个引用副本。这个时候,方法内的a和方法外的a是指向同一个对象(A@18a992f)。

④说明,在方法内,改变了a的副本的引用,指向了a2所指向的这个对象(A@4f1d0d),并没有改变方法外a的引用。

⑧说明,在方法内a=a2前,对a的操作实际上就是对方法外a的操作,因为他们指向的是同一个对象(A@18a992f)。

图例:



黑线是在方法内
红线是刚刚进入方法
蓝线是a=a2操作完成后的效果

所以当a=a2操作后,对a的任何操作都不发改变方法外的a的值。
但是如果是按引用传递,则a=a2操作后,方法外的值也就跟着改变了!

所以,java是按值传递的!!
  • 大小: 17.8 KB
分享到:
评论
3 楼 shuangwhywhy 2013-01-16  
pmh905001 写道
如何证明这个副本是内存中真实存在的?这个副本就是作者凭空想象的东西。如果很深调用栈,那岂不是要创建很多副本?那这些副本又放在哪儿?这个像c语言的指针,传递的是一个地址的值而已。


我提醒你,C 语言本身就是按值传递的,因为它根本不支持按引用传递,无论你用什么方法模拟,你用指针,它依然是在函数调用时拷贝出一个相同指针来。
2 楼 jwx0925 2012-03-06  
pmh905001 写道
如何证明这个副本是内存中真实存在的?这个副本就是作者凭空想象的东西。如果很深调用栈,那岂不是要创建很多副本?那这些副本又放在哪儿?这个像c语言的指针,传递的是一个地址的值而已。



如果是基本对象,传递的是副本。

如果是对象,传递的是对象的引用的副本。引用的副本,实际上也是值。

理解原理,不必纠结“按值”或者“按引用”
1 楼 pmh905001 2012-03-05  
如何证明这个副本是内存中真实存在的?这个副本就是作者凭空想象的东西。如果很深调用栈,那岂不是要创建很多副本?那这些副本又放在哪儿?这个像c语言的指针,传递的是一个地址的值而已。

相关推荐

    谈谈Java中的i++

    在eclipse中运行如下代码,很多小伙伴在纠结到底应该是多少,其实正确结果应该是0!!! int i = 0; i = i++; System.out.println("i的值是 : " + i); 这是和JVM的内存分配有关,JVM在处理这段带代码时,会先把i++的...

    [Java]Ibatis Spring Integration Demo

    Demo代码,没有啥太多的功能,就是对一张表的getAll(),然后输出结果的count值(.net下习惯了list.count,java是size,唉,老不习惯了,多写写java估计以后又习惯size,为啥人总是那么纠结呢?),数据库就不上了,...

    不再纠结Java中的String类

    string的种种,纠结,希望这篇文章让大家不再纠结。。  String是我们经常用到的一个类型,其实有时候觉得写程序是在反复的操作字符串,这是C的特点,在java中,jdk很好的封装了关于字符串的操作。主要讲的是三个...

    Java实现简单在线播放器——支持优酷和土豆

    Java实现简单在线播放器——支持优酷和土豆 。原理很简单。纠结的是要知道土豆跟优酷是的视频播放需要哪些参数。更多请参看http://blog.csdn.net/cannel_2020/article/details/7953257 或 者...

    java_ssm办公自动化系统毕业论文.doc

    本文档资料适用于java php ssm springboot Vue python nodejs 微信小程序 Android app等,写文档不要纠结于是什么语言的 只需要把文中的内容替换成你需要的就行了哦,最少文档的各种图,比如说功能模块图,流程图,用列图...

    java 处理大数模板

    原来令人纠结的大数问题 用java处理起来那么容易 汗

    java_ssm Android校园跑腿代办助手app毕业论文.doc

    本文档资料适用于java php ssm springboot Vue python nodejs 微信小程序 Android app等,写文档不要纠结于是什么语言的 只需要把文中的内容替换成你需要的就行了哦,最少文档的各种图,比如说功能模块图,流程图,用列图...

    Android、iPhone和Java、php四个平台一致的3des加密的类

    先前一直在做java服务器,最近要开发用到php,这其中遇到的最让人纠结的要属php、Android和iPhone三个平台加解密不一致的问题。因为手机端后台通常是用php开发的Web Service,Android和iPhone客户端调用同样的Web ...

    java基础 编辑器IntelliJ IDEA.rar

    IDEA 全称 IntelliJ IDEA,是 java 编程语言开发的集成环境。IntelliJ 在业界被公认为最好的 java 开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE 支持、各类版本工具(git、svn 等)、JUnit、CVS 整合...

    Java解析之纠结的DBF文件

    NULL 博文链接:https://qindongliang.iteye.com/blog/1941485

    JAVA打印类是POS小票

    也许你和我一样,打印POS小票遇到很多问题。比如乱码、布局,我也是和你一样纠结了好几天才弄出来。我这个范例希望能帮助你,不用积分下载

    Java与c语言 DES加密互通

    实现了JAVA加密,C语言实现解密的功能,问题当时纠结了好久,终于实现了,给大家分享一下

    Java虚拟机

    当我看完这本书明白,原来在方法调用时候这些东西就生成处理,另外还有一个new到底经历那些事情等等一序列问题,如果你还在就纠结一些问题为什么是这么处理的时候那你就去看Java虚拟机吧,或许会有不一样的感悟,...

    Java中的String不再纠结

    string的种种,纠结,希望这篇文章让大家不再纠结。。 string是我们经常用到的一个类型,其实有时候觉得写程序是在反复的操作字符串,这是C的特点,在java中,jdk很好的封装了关于字符串的操作。主要讲的是三个类...

    java Swing 组件

    这里收集了java的大多数组件的应用,同时让你掌握java Swing组件的应用 ,使得你学习java的gui也不再那么纠结,

    小程序登录、微信网页授权(Java版)

    首先呢,“登录”、“授权”、“授权登录”,是一样的意思,不用纠结。 写小程序授权登录的代码前,需要了解清楚openid与unionid的区别,这里再简单介绍一下: 腾讯有个 “微信·开放平台”,只有企业才能注册账号,...

    JAVA精品休闲益智游戏《海盗向前冲》源码

    JAVA精品休闲益智游戏《海盗向前冲》源码 说明: 带有童话色彩的益智游戏。小海盗被困住啦,怎么才能帮助他逃离这个危险的地方呢?游戏的关卡设计非常不错,难度循序渐进,足够你纠结上一阵子了。源码包含完整工程 ...

    塔防游戏--java游戏

    塔防游戏--java游戏处女作之,正在纠结的同学可以做个参考

    Java安全框架Shiro电子书

    Apache Shiro 是Java 的一个安全框架。目前,使用Apache Shiro 的人越来越多,因为它相 当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时 可能并不需要那么复杂的东西,所以...

    java ssm超市管理系统毕业论文.docx

    本文档资料是本人原创,适用于java php ssm springboot Vue python nodejs 微信小程序 Android app等,写文档不要纠结于是什么语言的 只需要把文中的内容替换成你需要的就行了哦,最少文档的各种图,比如说功能模块图,...

Global site tag (gtag.js) - Google Analytics