值传递是对基本型变量而言的,传递的是该变量的一个副本,即“复制”了一份值给目标,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。
引用传递可以看做是一种特殊的值传递,传递的值为变量的地址。
几个例子:
假设num=10,
例子1:
void foo(int value) {
value = 100;
}
foo(num); // num 没有被改变
这个例子中相当于num的值(10)首先被复制给了局部变量value,而后value的值被改为100,方法执行完毕,系统释放方法栈,局部变量value也会被销毁。num不受影响。
例子2:
void foo(String text) {
text = "windows";
}
foo(str); // str 也没有被改变
由于String是引用类型,局部变量text首先接受str传递的地址值(str对应字符串的地址值),指向windows, 而后text指向被改变,指向“windows”的地址值,整个过程str不受影响。
例子3:
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。
当局部变量builder指向 sb所指的 StringBuilder("iphone")时,执行了append方法,因此这个对象会被改变,然后builder变量再被销毁。好比A和B共同在一个房间里,B对房间做了一些改变,然后离开了房间,此时剩下A和被改变的房间。
例子4:
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。
和例子3相比较,局部变量builder首先接收到sb对应的地址值,指向''iphone"。而后又在方法中指向新对象"ipad"。整个过程变量sb不受影响。