1,按值传递和按引用传递
按值传递:当将一个参数传递给另一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值不受影响。
按引用传递:意味着一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此函数修改该参数,原始值也会改变。
一个 C的例子
void Modify(int p, int * q)
{
p = 27; // 按值传递 --- p是实参a的副本, 只有p被修改
*q = 27; // q是b的引用,q和b都被修改
}
int main()
{
int a = 1;
int b = 1;
Modify(a, &b); // a 按值传递, b 按引用传递,
// a 未变化, b 改变了
return(0);
}
2,Java 中的按值传递
Java 中的所有参数传递都是传值.而不是传引用。
所有的参数传递(原始值传递还是对象的传递)都会在程序运行栈 上重新分配一个值的副本,所有的操作和赋值都是对这个 副本 进行操作.
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
输出为:
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
对副本操作,能够改变成员变量,因为参数“值”副本是一个地址,能够正确指向成员变量的位置。因此,arg1 变量x,y 还是指向原来的 pnt1 的a 变量。 对副本arg1的操作可以改变对象的值。
而赋值没用,因为只是改变了当前函数栈内副本的内容,而没有改变上一层函数栈内的 对应“值”。交换只是对引用的副本arg1 , arg2起了作用。
public static void main(String[] args) {
StringBuffer bs1= new StringBuffer("buffer1");
StringBuffer bs2=new StringBuffer("buffer2");
test(bs1,bs2);
System.out.println(bs1);
System.out.println(bs2);
}
static void test(StringBuffer bs1,StringBuffer bs2) {
System.out.println(bs1);
System.out.println(bs2);
bs2=bs1;
bs1=new StringBuffer("new");
System.out.println(bs1);
System.out.println(bs2);
bs1.append("+test");
//StringBuilder的值可以改变
bs2.append("+test");
}
输出:
buffer1
buffer2
new
buffer1
buffer1+test
buffer2
参考:
http://www.cnblogs.com/bosnma/p/4256108.html;
http://www.importnew.com/3559.html;
http://www.iteye.com/topic/12961;
http://www.cnblogs.com/perfy/archive/2012/10/16/2726039.html