关于Java的值传递咱们知道:Java中基本类型做为函数参数传递就是值传递,不管在函数中对传进去的值作什么操做,函数外面声明的变量值都不会有什么改变,而对象做为函数参数传递进去则否则,为何说否则呢,请看下面的代码。
bash
下面的代码中有三个函数,一个值传递,两个引用传递app
package com.learn;
public class main {
public static void change(int data){//值传递
data = data+1;
}
public static void changeref(StringBuffer data){//引用传递1
data = new StringBuffer("in changeref");
}
public static void changeref_2(StringBuffer data){//应用传递2
data.append(" now changed");
}
public static void main(String[] args){
int num = 10;
System.out.println("num before changed: "+num);
change(num);
System.out.println("num after changed: "+num);
StringBuffer str = new StringBuffer("outside");
System.out.println("str before changed: "+str);
changeref(str);
System.out.println("str after changed: "+str);
StringBuffer str_2 = new StringBuffer("outside");
System.out.println("str_2 before changed: "+str_2);
changeref_2(str_2);
System.out.println("str_2 after changed: "+str_2);
}
}
复制代码
num before changed: 10
num after changed: 10
str before changed: outside
str after changed: outside
str_2 before changed: outside
str_2 after changed: outside now changed
Process finished with exit code 0
复制代码
从代码的运行结果能够看到,不出意料的,咱们能够看到基本类型int的值在通过函数操做后没有任何变化,而一样是引用传递str与str_2的结果却彻底不一样,这是为何呢?jvm
回到代码,能够发现,changeref()函数中data直接指向了一个新的StringBuffer对象,通过此操做后函数外的str值并无任何改变,而changere_2()函数中data是日后追加了一段字符串,此操做后函数外的str_2值改变了。这是为何呢?ide
在讨论这个问题以前,先来讨论一下什么是值传递,什么是引用。首先值传递的概念是将值复制一份传入函数。而引用的概念就涉及到了jvm存储模型,在jvm存储模型中,基本类型都是直接存在Java虚拟栈中的,而对象都是新建在堆区,要想访问位于堆区的对象,须要在Java虚拟栈中创建一个变量,它的值是:指向某个对象的地址,这个变量就是引用。函数
而在Java中并无真正的引用传递,一般所说的引用传递其实也是值传递。而在上面的代码中,changeref()直接改变data的值是对复制过来的引用值进行改变,changeref_2()是对data指向的对象进行操做,换言之就是对堆中的对象进行改变,因此就出现这样的结果。ui