在java确实都是采用值转递。 当在java中声明一个变量时,它们都会有两个值空间,一个是它的地址值空间,一个是它的具体值空间。 当发生转递时,都是以地址值空间的值来进行转递。那么,问题来了,当我们进行基础数据类型及类String的转递时,为什么看起来好像是跟C++中的值转递是一样的呢?这是因为,基础数据类型及类String他们的引用的值是不可改变的。 比如:int i = 0; i 的指针地址为x000,具体值为0.有方法 void changI(int i) { System.out.println(i);//A i = 1;//B } 分析:changI的int i 为i定义一个指针地址,假如为x111,但把i作为参数调用changI(int i)时,changeI中的i同样指向具体值0.当我试图改变i的值时,由于基本数据类型及String类型的数据是常量值(值不可改变),所以JAVA会常量池中新增一个值1.然后changI中的地址指向这个新值。所以基本数据类型及String类型的转递看起来像C++中值转递。至于其他类型的转递就不多说了,跟C++的引用是一个道理的,只是说法不同罢了。只要记住,常量值不可改变,对象值可改变这个原理就容易理解了。
就是C++里的传引用,对CPU而言,也是“值”,关键问题是,函数里对这个“值”的解释是不一样的,可能就是数据本身,可能是个地址,可能是地址的地址,等等。至于pass by value,pass by reference,是编译中的概念,这里提到的“值”和“引用”是有自己的范畴的。纠结的根源在于,SUN 发明Java的人,把“对象句柄”称为“引用”,这个“引用”不同于编译中“pass by reference” 的"reference",导致一些人的误解,再去误导别人。绝对的看“一切都是值”,就像“人都是动物”,话对,但意义是什么呢?
当在java中声明一个变量时,它们都会有两个值空间,一个是它的地址值空间,一个是它的具体值空间。
当发生转递时,都是以地址值空间的值来进行转递。那么,问题来了,当我们进行基础数据类型及类String的转递时,为什么看起来好像是跟C++中的值转递是一样的呢?这是因为,基础数据类型及类String他们的引用的值是不可改变的。
比如:int i = 0; i 的指针地址为x000,具体值为0.有方法
void changI(int i)
{
System.out.println(i);//A
i = 1;//B
}
分析:changI的int i 为i定义一个指针地址,假如为x111,但把i作为参数调用changI(int i)时,changeI中的i同样指向具体值0.当我试图改变i的值时,由于基本数据类型及String类型的数据是常量值(值不可改变),所以JAVA会常量池中新增一个值1.然后changI中的地址指向这个新值。所以基本数据类型及String类型的转递看起来像C++中值转递。至于其他类型的转递就不多说了,跟C++的引用是一个道理的,只是说法不同罢了。只要记住,常量值不可改变,对象值可改变这个原理就容易理解了。