结论:
Java 中的所有函数调用都是值传递。
值传递是指,函数在调用时,传递的参数不是实参本身,而是它的副本。
引用传递是指,函数在调用时,传递的参数就是实参本身(的地址)。
在Java中
public class A { public int a; } public class ValueOrPointer { public static void main(String args[]) { A a1 = new A(); a1.a = 1; A a2 = new A(); a2.a = 2; function(a1, a2); System.out.println("\n在main函数里面:\n"+a1+"值:"+a1.a); } static void function(A a1, A a2) { System.out.println("在被调里面:\n引用改变之前:"); System.out.println(a1+"值:"+a1.a); a1 = a2; System.out.println("改变形参引用后:"); System.out.println(a1+"值:"+a1.a); } }
结果:
说明:Java中,形参是重新拷贝了一份实参的值(一个指向堆中的地址ID)
C/C++中:
C++指针传递:
void function(int* p) { p++; std:cout << *p << endl; } int main() { int array[3] = {1,2,3}; int* p = array; function(p); std:cout << *p<<endl; }
结果:
说明:C/C++中,单纯传送指针时,形参也是复制了实参的指针值。
C++的引用传递:
void function(int& p) { p++; std::cout<< p << endl; } int main() { int array[3] = {1,20,3}; int*p = array; std::cout<< *p << endl; function(*p); std::cout<< *p<<endl; }
结果:
void function(int* &p) { //这里是一个指针的引用——p是int* 类型,但是是个引用 std::cout<< *++p+1 << endl; } int main() { intarray[3] = { 1,20,30 }; int*p = array; std::cout<< *p << endl; function(p); std::cout<< *p << endl; }
结果
关于引用的理解:引用,可以理解成“起别名”,一个变量可以有许多个别名。
引用就是用指针实现的,但是表现的语法状态就像是原值一样使用。
直接输出引用就是,原值
void function2(int &p) { std::cout << p<< endl; } int main() { int array[3] = {4,20,30 }; int* p = array; function2(*p); }
再如下面:
void swap(int &a, int &b){ int tmp = a; a = b; b = tmp; }
就节省了程序员写指针的时候不停要*a = *b;
能用引用的地方都是可以用指针代替的!但是引用更安全好用,不容易造成野指针之类的
所以,到这里,就可以知道,Java绝对是只有值传递。
有的书上自己搞混乱了,
比如,有的书上认为 “传递的是基本类型比如 intdouble之类的就是值传递
而传地址就是引用传递,所以java是值传递和引用传递都有的语言”
这是很荒谬的,按照这么说,所有语言都能在子函数/方法中传递基本类型和地址类型,那么所有的语言都是值传递和引用传递了??
值传递和引用传递的区别仅仅在于形参值是实参的拷贝副本还是实参的本身!