Java到底是值传递?还是引用传递?
2016-02-17 14:23
295 查看
前言
最近和同事讨论算法效率问题无意中涉及到一个问题,java中调用方法的时候是值传递呢?还是引用传递?网上搜索一下相关问题,众说纷纭![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/curse.gif)
,有人说值传递,有人说引用传递,还有人说”基础类型是值传递,对象类型是引用传递“。那么我们就用简单客观的代码分析一下
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/cute.gif)
。
值传递
值传递是指将该值复制一份出来使用,比如a复制一份a1出来,a1做的操作不会影响到a。例子如下:<span style="white-space:pre"> </span>public static void methodOne(int a) { a++; System.out.println("methodOne a="+a); } public static void main(String[] args) { int a = 100; methodOne(a); System.out.println("main a="+a); }
输出结果为:
methodOne a=101
main a=100
很明显这是值传递。不多解释。主要的问题出现在下面引用传递
引用传递
引用传递是将该值的地址传递给方法,比如取a的地址值b,b指向a,可以通过b找到a并对a进行修改。这时候a的值就会改变。废话不多说,上代码:<span style="white-space:pre"> </span>public static void methodTwo(List<Integer> a) { a.add(101); } public static void main(String[] args) { List<Integer> a = new ArrayList<Integer>(); a.add(100); methodTwo(a); System.out.println("main a="+a.toString()); }
运行的结果如下:
main a=[100, 101]
这时候,很多人会说,看,java中的基本类型是值传递,对象类型是引用传递。如果这样认为的话,那就大错特错了。再来看看下面的代码:
<span style="white-space:pre"> </span>public static void methodTwo(List<Integer> a) { a = new ArrayList<Integer>();// 就在这加了这一句 a.add(101); } public static void main(String[] args) { List<Integer> a = new ArrayList<Integer>(); a.add(100); methodTwo(a); System.out.println("main a="+a.toString()); }
运行结果如下:
main a=[100]
这时候应该很多人就蒙逼了
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/ohmy.gif)
,这算闹哪样呀,不是引用传递吗?应该是main a=[101]才对的呀!现在我们静下来分析一下,java中方法之间传递对象参数的内存变化是怎样的?来,我们从代码一句一句分析下来。
<span style="white-space:pre"> </span>List<Integer> a = new ArrayList<Integer>();
这时候内存里边会有这样一个模型(图不是很漂亮,大家将就一下
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/cute.gif)
):
当调用methodTwo方法时,模型变如下:
这时候应该就清晰很多了,对象引用a被复制了一份出来使用,methodTwo拿到的是a的复制品。当methodTwo中调用
<span style="white-space:pre"> </span>a = new ArrayList<Integer>();模型变化如下:
这时候应该都恍然大悟了吧。在new一个新的对象出来之后,methodTwo方法的a指向了新的对象实例,所以怎么改变都不会改变main方法中a的对象。同时也可以证明,java中只有值传递没有引用传递,在传递对象时,是传递对象的引用的副本,不是直接传递对象的引用本体。
总结
java这个特性应该很多人都不太了解,因为这种东西很少人去探究,敲代码敲多了,反反复复都是这样的语句,没有时间去思考也觉得没必要去思考。但一旦出现bug,就会难倒一堆人。一个小问题就会涉及到java底层的原理。这是我个人第一篇技术博文,希望对你有所帮助
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif)
。哈哈,第一篇呢,第一篇呢,
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/proud.gif)
有点小激动,每周一更,希望能做到。
(唉,这篇文章文字还是很少,因为本人语言功能性短缺
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
,写的不好请多多指正,程序员看看图应该懂吧
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
)
相关文章推荐
- java实现复制功能
- Java中的hashCode和equals方法学习
- struts2和springMVC的区别
- JVM中的本地方法栈(Native Method Stacks)和Java虚拟机栈(Java Virtual Machine Stacks)
- java23中设计模式
- 打印九九乘法表算法-java
- 第二章 Javac编译原理
- java 类执行顺序 +变量赋值顺序
- java 中 split()方法应用
- 使用new和反射产生java内部类的实例化对象
- java IO复习笔记
- Java变量以及内存分配
- java 把字符串中的反斜杠(\)替换成(\\)和反斜杠(/)替换成(\)
- RxJava学习笔记(1) - RxJava简介
- Java并发编程:性能、扩展性和响应
- Android服务端开发-使用Eclipse搭建Java Web服务端
- 浅析Java中的final关键字
- java对象的生命周期及回收
- Java——用户激活邮件工具类
- as导入eclipse项目出现There are unrecoverable errors which must be corrected first