java值传递还是引用传递
2018-03-08 10:37
218 查看
值传递
值传递是指将该值复制一份出来使用,比如a复制一份a1出来,a1做的操作不会影响到a。例子如下:[java] view plain copy<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的值12d9d
就会改变。废话不多说,上代码:[java] view plain copy<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中的基本类型是值传递,对象类型是引用传递。如果这样认为的话,那就大错特错了。再来看看下面的代码:[java] view plain copy<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]这时候应该很多人就蒙逼了
,这算闹哪样呀,不是引用传递吗?应该是main a=[101]才对的呀!现在我们静下来分析一下,java中方法之间传递对象参数的内存变化是怎样的?来,我们从代码一句一句分析下来。[java] view plain copy<span style="white-space:pre"> </span>List<Integer> a = new ArrayList<Integer>();
这时候内存里边会有这样一个模型(图不是很漂亮,大家将就一下
):
当调用methodTwo方法时,模型变如下:
这时候应该就清晰很多了,对象引用a被复制了一份出来使用,methodTwo拿到的是a的复制品。当methodTwo中调用[java] view plain copy<span style="white-space:pre"> </span>a = new ArrayList<Integer>();
模型变化如下:
这时候应该都恍然大悟了吧。在new一个新的对象出来之后,methodTwo方法的a指向了新的对象实例,所以怎么改变都不会改变main方法中a的对象。同时也可以证明,java中只有值传递没有引用传递,在传递对象时,是传递对象的引用的副本,不是直接传递对象的引用本体。
首先看一段代码:
public static void main(String[] args) { Person a = new Person(23, "a"); Person b = new Person(22,"b"); System.out.println("改变前a:"+a+"\nb:"+b); changeValue(a,b); System.out.println("改变后a:"+a+"\nb:"+b); } private static void changeValue(Person a, Person b) { a.setAge(10); b.setAge(11); }1
2
3
4
5
6
7
8
9
10
11
12
输出:
改变前a:Person [age=23, name=a] b:Person [age=22, name=b]
改变后a:Person [age=10, name=a] b:Person [age=11, name=b]然后我们要明确一下值传递和引用传递的概念:
值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。
引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
参考博客园我们都知道,Java的方法传递的是对象引用,形参和实参指向同一个对象的内存地址,所以形参修改对象的状态时,实参指向的对象状态也会发生变化。上面的实例很容易让人认为Java是引用传递,因为形参对象的状态改变直接反应在实参对象上了!再看一段代码:
public static void main(String[] args) { Person a = new Person(23, "a"); Person b = new Person(22,"b"); System.out.println("交换前a:"+a+"\nb:"+b); swap(a, b); System.out.println("交换后a:"+a+"\nb:"+b); } private static void swap(Person a, Person b) { Person temp = a; a = b; b = temp; }1
2
3
4
5
6
7
8
9
10
11
12
输出:
交换前a:Person [age=23, name=a] b:Person [age=22, name=b]
交换后a:Person [age=23, name=a] b:Person [age=22, name=b]很奇怪吧! 为什么a和b的值没有交换呢? 按照Java是引用传递的假设,a和b的指向的对象会发生交换啊!很多程序设计语言(特别是C++和Pascal)提供了两种参数传递的方式:值传递和引用传递。有些程序猿(甚至本书的作者)认为Java对对象采用的是引用传递,实际上,这种理解是不对的。–《Core Java Volume I》第9版P122实际上,结合上面一个实例和值传递引用传递的概念,我们可以发现,Java方法的传值,实际上是把实参的值—-对象引用(对象的内存地址)传递给了形参,从而形参和实参的值(即变量里存储的内存地址,非变量本身的内存地址)是相同的,指向了同一个对象/内存地址。
总结
值传递的时候,将实参的值,copy一份给形参。引用传递的时候,将实参的地址值,copy一份给形参。
实际上,结合上面一个实例和值传递引用传递的概念,我们可以发现,Java方法的传值,实际上是把实参的值—-对象引用(对象的内存地址)传递给了形参,从而形参和实参的值(即变量里存储的内存地址,非变量本身的内存地址)是相同的,指向了同一个对象/内存地址。所以我们得到如下结论:Java的参数传值方式是值传递,而非引用传递
相关文章推荐
- Java:按值传递还是按引用传递详细解说
- java参数传递(值传递还是引用传递)
- java到底是值传递还是引用传递?
- 【Stackoverflow好问题】Java是按值传递还是按引用传递
- Java是值传递还是引用传递?
- Java:按值传递还是按引用传递详细解说
- Java:按值传递还是按引用传递详细解说
- java 引用传递,还是值传递 之坑
- 画重点,Java方法的参数到底是值传递还是引用传递?
- Java中参数传递是值传递,还是引用传递
- JAVA是按值传递还是按引用传递的,试试就知道
- java 方法中参数是值传递还是引用传递
- Java中函数是值传递还是引用传递?
- java参数传递,引用还是拷贝
- Java中到底是值传递还是引用传递?
- Java:按值传递还是按引用传递详细解说
- Java的参数传递到底是引用传递还是值传递
- Java:按值传递还是按引用传递详细解说
- 面试之路(18)-java的函数参数传递类型之值传递还是引用传递
- Java:按值传递还是按引用传递详细解说