java 传参引用怎么写_Java传参问题——传引用还是传值???

首先非常确定地说:如果你对“传引用”、“传值”的理解是来源于C 或 C++中指针问题的话,那么Java的参数传递就是传值!

想到考虑这个问题是在读java.util的Timer源码时看到了这几条语句

TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp;刚一看是正常的交换语句,但一想难道不是“Java的所有对象皆为引用”吗?这样的话tmp就和queue[j]是同一个引用,queue[j] = queue[k]时不应该也相当于tmp = queue[k]吗?为什么能够完成交换呢?

之后自己也写了类似的测试,果然可以交换!然后把交换部分写在一个方法里,像这样

public class Main

{

public static void main(String[] args)

{

copyTest();

}

private static void copyTest()

{

A a1 = new A(1);

A a2 = new A(2);

A tmp = a1;

a1 = a2;

a2 = tmp;

System.out.println("*******after swapping*******");

System.out.println("a1 = " + a1.id);

System.out.println("a2 = " + a2.id);

/*************/

a1 = new A(1);

a2 = new A(2);

swap(a1, a2);

System.out.println("*******after swapping in function*******");

System.out.println("a1 = " + a1.id);

System.out.println("a2 = " + a2.id);

}

private static void swap(A o1, A o2)

{

A tmp = o1;

o1 = o2;

o2 = tmp;

}

}

class A

{

public int id = 0;

public A(int id)

{

this.id = id;

}

}

结果是:

*******after swapping*******

a1 = 2

a2 = 1

*******after swapping in function*******

a1 = 1

a2 = 2

也就是在方法中没有完成交换!到这里突然感觉自己非常LOW逼,因为大一什么都不懂的时候还在来回的倒腾关于传值传指针传引用的问题,现在Java写了这么长时间(相对于更短暂的写C的时间而言)竟然还没搞懂Java方法传参是传值还是传引用的问题。

于是只能去搜索,在网上找到一篇很不错的讲解:http://blog.csdn.net/wyzsc/article/details/6341107

其中所说也终于解开了我的迷惑:Java向方法传递参数时传递的是值,引用的值,就像C/C++中传地址一样,传递过去地址被形式参数复制出了独立的一份。

当程序运行到

private static void swap(A o1, A o2)时,内存中应该是这个样子:

执行到这一句

0818b9ca8b590ca3270a3433284dd417.png

A tmp = o1;内存中应该是这个样子:

0818b9ca8b590ca3270a3433284dd417.png

当运行到

o1 = o2;内存中应该是这个样子:

0818b9ca8b590ca3270a3433284dd417.png

当运行到这一句

o2 = tmp;内存中应该是这个样子:

0818b9ca8b590ca3270a3433284dd417.png

至此交换完成,从图中明显可以看出:虽然参数o1、o2完成了交换,但那其实只是他们指向的内存区域的箭头发生了变化,即参数传递是传值,并非是他们所指向的内存区域发生了变化,即传引用。

同样我写了一段C++的代码

#include

using namespace std;

class A

{

public:

int id = 0;

A(int tid)

{

id = tid;

}

};

void mySwapByValue(A o1, A o2)

{

A tmp = o1;

o1 = o2;

o2 = tmp;

}

void mySwapByReference(A &o1, A &o2)

{

A tmp = o1;

o1 = o2;

o2 = tmp;

}

void mySwapByCopyingAddress(A *o1, A *o2)

{

A *tmp = o1;

o1 = o2;

o2 = tmp;

}

int main()

{

A a1 = NULL;

A a2 = NULL;

/*********************part1**************************/

a1 = A(1);

a2 = A(2);

A tmp = a1;

a1 = a2;

a2 = tmp;

cout << "*********after swapping************" << endl;

cout << "a1 = " << a1.id << endl;

cout << "a2 = " << a2.id << endl;

/****************************************************/

/*********************part2**************************/

a1 = A(1);

a2 = A(2);

mySwapByValue(a1, a2);

cout << "*********after swapping in mySwapByValue************" << endl;

cout << "a1 = " << a1.id << endl;

cout << "a2 = " << a2.id << endl;

/****************************************************/

/*********************part3**************************/

a1 = A(1);

a2 = A(2);

mySwapByReference(a1, a2);

cout << "*********after swapping in mySwapByReference************" << endl;

cout << "a1 = " << a1.id << endl;

cout << "a2 = " << a2.id << endl;

/****************************************************/

/*********************part3**************************/

a1 = A(1);

a2 = A(2);

mySwapByCopyingAddress(&a1, &a2);

cout << "*********after swapping in mySwapByCopyingAddress************" << endl;

cout << "a1 = " << a1.id << endl;

cout << "a2 = " << a2.id << endl;

/****************************************************/

return 0;

}

运行结果是:

*********after swapping************

a1 = 2

a2 = 1

*********after swapping in mySwapByValue************

a1 = 1

a2 = 2

*********after swapping in mySwapByReference************

a1 = 2

a2 = 1

*********after swapping in mySwapByCopyingAddress************

a1 = 1

a2 = 2

上述Java中的交换方法非常类似于这段C++代码中的mySwapByCopyingAddress函数。实质也是传值,传递引用的值。

因此,Java方法的参数传递是传值并非传引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值