Java 对象作为参数传递的相关原理研究
来源:互联网 发布:ubuntu u盘挂载路径 编辑:程序博客网 时间:2024/04/30 15:51
一、
Java编程中,当对象作为参数传递给方法时候,是按引用传递的,但是有的人会说这实质上是按值传递的。其实两者说的都不错,只是理解的方式不一样罢了,二者的原理其实是一样的。
二、
下面通过一个例子来详细说明Java对象作为方法参数的时候会出现的情况:
import java.util.ArrayList;import java.util.List;/** * 测试java的引用传值 * * Created by Xuyh at 2017/01/05 上午 10:27. */public class SetParamTest {public static void main(String... args) {// 集合对象,列表[a, b, c]List<String> testParam = new ArrayList<String>();testParam.add("a");testParam.add("b");testParam.add("c");System.out.println("Old: " + testParam.toString() + "\r\n");// 引用(地址)传值,并直接修改testParam指向对象的值change(testParam);System.out.println("Change1: " + testParam.toString() + "\r\n");testParam.add("a");// 引用(地址)传值,修改指向对象之后再将地址返回testParam = change2(testParam);System.out.println("Change2: " + testParam.toString() + "\r\n");// 集合对象变为[b, c, d, e]testParam.add("d");testParam.add("e");// 引用(地址)传值,方法内部new新集合对象并将地址赋给方法局部参数,// 并不改变testParam的值,testParam仍然指向原地址sort(testParam);System.out.println("sort1: " + testParam.toString() + "\r\n");// 引用(地址)传值,方法内部new新集合对象并将地址赋给方法局部参数,// 并将新地址返回,再赋值给testParam,因此testParam指向的对象发生改变testParam = sort2(testParam);System.out.println("sort2: " + testParam.toString() + "\r\n");}public static void change(List<String> param) {if (param.contains("a"))param.remove("a");}public static List<String> change2(List<String> param) {if (param.contains("a"))param.remove("a");return param;}public static void sort(List<String> param) {List<String> newParam = new ArrayList<String>();for (int i = param.size() - 1; i >= 0; i--) {newParam.add(param.get(i));}param = newParam;}public static List<String> sort2(List<String> param) {List<String> newParam = new ArrayList<String>();for (int i = param.size() - 1; i >= 0; i--) {newParam.add(param.get(i));}return newParam;}}
上面的例子简单的说就是一个列表,[a, b, c],首先通过两个方法把其中的字符”a”去除,然后通过两个方法对列表[b, c, d, e]进行倒序排序。同时在操作的过程中不断将main方法中的testParam输出出来。
接着请看程序运行的结果:
Old: [a, b, c]Change1: [b, c]Change2: [b, c]sort1: [b, c, d, e]sort2: [e, d, c, b]
由结果可以看到,两个change方法都将原来的testParam改变了,而sort方法只有一个改变了testParam的值,这个有趣的现象接下来要好好说说了。下面从四个比较典型的方法来介绍不同情况下对象作为值传入方法时候内存中的情况,以便我们更好理解java的方法传值原理。
三、
change方法
public static void change(List<String> param) {if (param.contains("a"))param.remove("a");}
testParam作为参数传递给param时候,内存内是这样的:
testParam的地址值复制给了change方法局部变量param,于是param指向了与testParam相同的一个对象。注意这时候param的引用(地址)值是testParam的一份拷贝。
Change方法中将列表的”a”元素去除时候的情况是这样的:
此时testParam与param指向的对象(同一个)发生了改变,所以方法执行完毕之后输出testParam是发生改变的。
change2方法
public static List<String> change2(List<String> param) {if (param.contains("a"))param.remove("a");return param;}
与change方法类似,当对象在方法中发生改变时候,内存中的情况是这样的:
testParam = change2(testParam);
方法执行到最后,param会返回,也就是param的引用(地址)值会返回,然后又拷贝给testParam(其实是多此一举,二者的地址值完全相同)。所以方法执行完成之后输出的testParam是发生改变的。
sort方法
public static void sort(List<String> param) {List<String> newParam = new ArrayList<String>();for (int i = param.size() - 1; i >= 0; i--) {newParam.add(param.get(i));}param = newParam;}
调用方法时候内存中是这样的
接着,方法中new了一个新的对象,并在处理排序之后将新对象的引用(地址)赋值给param,这时候内存中的情况是这样的:
可以看到,testParam与param指向的已经不是同一个地址了,并且testParam指向的对象仍然没有发生改变。因此方法执行完毕之后输出的结果看来,sort方法是没有用的。
sort2方法
public static List<String> sort2(List<String> param) {List<String> newParam = new ArrayList<String>();for (int i = param.size() - 1; i >= 0; i--) {newParam.add(param.get(i));}return newParam;}
同sort方法类似,执行sort2方法前内存中是这样的:
新对象排序完成后是这样的:
这时候testParam与param都是指向原来的对象
方法的最后把newParam返回,即将newParam的引用(地址)值返回,在main方法中将其赋值给testParam
testParam = sort2(testParam);
然后内存中就是这样的了:
因此经过返回后的sort2方法是有作用的。
四、
小结:
通过以上的分析可以得出,Java中对象作为方法参数传递的是对象引用(地址)值的拷贝,通俗的讲,就是拷贝了一把钥匙,main方法中的钥匙跟被调用方法中参数的钥匙对应能打开的房间是相同的,但是是不同的钥匙。如果在被调用方法中,参数钥匙被修改了(new了一个新对象并赋值给参数钥匙),不会影响main方法钥匙指向的房间。这点是值得注意的。
因此如果想要在被调用方法中不修改参数指向的对象,可以通过new一个新的对象来实现,但是如果想要new一个新的对象并使main方法该对象变成这个新的对象,就要将其作为返回值返回并赋值给旧对象变量了。
- Java 对象作为参数传递的相关原理研究
- Java 对象作为参数传递的相关原理研究
- 对象作为参数传递的相关问题
- Java中接口对象作为参数传递
- 指针作为参数传递的相关问题
- .net对象作为参数传递的注意事项
- 对象作为方法的参数连续传递
- 对象作为方法的参数传递
- .net中引用传递对象作为参数传递的问题
- java的String类型作为参数传递
- java对象参数传递相关问题
- 将对象作为参数传递
- 我的Java开发学习之旅------>Java String对象作为参数传递的问题解惑
- java的参数传递原理
- java笔试陷阱:对象引用作为参数传递时陷阱
- 关于Java对象作为参数传递是传值还是传引用的问题
- Java对象的参数传递
- java中参数传递的研究
- Project file contains ToolsVersion="12.0". This toolset may be unknown or missing
- 收到银行承兑汇票应该注意什么
- vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
- 页面输入URL到response的过程
- HTML中的拖拉框----在路上(29)
- Java 对象作为参数传递的相关原理研究
- pycharm中修改python版本
- 告别被拒,如何提升iOS审核通过率(上篇)
- C++ Primer课后练习10.34~10.37,10.42
- linux环境配置maven
- highcharts用法
- html5 本地存储
- 【Java路径】问题
- 设置mysql workbench的sql_mode,ONLY_FULL_GROUP_BY不起作用