Java中函数参数的传递形式是值传递 还是引用传递

突然想到这个问题,不是很确定,然后查了一下资料,做一下总结. 


1.什么是值传递,什么是引用传递


值传递是将需要传递的值作为一个副本传递出去,例如:

int i = 5;

int j = i;

这里把i的值5拷贝了一份副本,作为j的值,结果是i = 5,j = 5.如果改变j的值,也就是拷贝出来的副本的值,

这个改变和原来的值毫无关系,因此改变j的值不会对i的值产生影响.


引用传递,是将引用对象的地址传递出去,例如:

int *p,*p1;

int i = 5; *p = i; //这里将i在内存中的地址赋与了指针p

p1 = p; //将指针p中的地址(即i的内存地址)赋与p1

此时,改变i的值,

i = 10;

由于指针p,p1指向的地址都是i的地址,因此*p 和 *p1 的值都是10.


2.Java中函数参数的传递形式

java中的数据分为基本数据类型和引用数据类型,我们来对这两种类型进行分析.

对于基本数据类型来说,举个例子:

int i = 10;

add(i);

void add(int temp){

temp +=5;

}

这个很简单,我们都知道调用函数时将i的值10拷贝给函数的参数了,函数调用结束后i的值并没有发生变化,这是很明显的值传递过程,我们来看看在内存中的变化过程.

首先在栈内存中为基本数据类型变量i分配内存空间并初始化值为10,然后开始调用函数add().执行add函数的时候,为temp变量分配栈内存空间,并将i的值拷贝给temp,在add执行之后,temp的值增加了5,随着add函数执行完毕,temp变量的生命周期结束了.可见,这个temp变量和i变量没有关系,temp变量可以随意命名,将其命名为i,也和之前申明的变量i毫无关系.

我找来一幅图,可以看看,在函数运行的时候,只是临时分配产生了一个值与i相同的另外一个变量而已,一旦完成了值得拷贝工作,之后这两个变量就没有任何联系了.因此,对这个临时变量的操作不会对i产生任何影响.

 


对于引用数据类型参数来说,举个例子:

class Person {

String name = "java";


public void setName(String name){

this.name = name;

}

}


 void changeName (Person p1){

p1.setName("javascript");

}

public static void main (String[] args){

Person p = new Person();

changeName(p);

}

我们来看看这一过程中内存中发生的变化:

首先在堆内存中创建了一个Person对象,然后在栈内存中创建了一个引用类型的变量p,p指向堆内存中的Person对象,即p的值为Person对象在内存中分配空间的首地址值.

调用changeName()函数时,栈中再次创建一个引用类型的变量p1,然后将p中的值拷贝给p1,即p1也指向Person对象. 调用完成后,p1指向的Person对象的name属性被改变为javascript.由于p和p1指向同一个Person对象,因此p指向的Person对象的name值也变为javascript.

这看起来类似于引用传递,但是这仍然是值传递,p1接受的值是p的值的拷贝,函数调用完成后,p的值完全没有改变,仍然是指向之前创建的Person对象,这就是值传递.

整个过程中改变的是Person对象的属性name,由于p和p1都指向这个Person对象,因此p和p1产生了相同的变化,使得看起来像是进行了引用传递.

如果是引用传递的话,那么p1接收的值将会是p的地址,那么p1将不会再指向Person对象,整个程序就会产生错误.

可见,引用数据类型的参数仍然是进行值传递的,只不过这里传递的值是对象在内存中的首地址,在java中即为指向该对象的引用.而引用传递是直接将变量的地址传递给参数,很明显,这样参数接收到的值将不再指向特定的对象,整个程序将会产生错误,要传递地址的话,应该是传递Person对象的地址而不是p对象的地址.

同样用图简单概括一下


 




概括一下,java中函数参数的传递方式是值传递,不管参数是基本数据类型还是引用数据类型.






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值