java的参数传递的值传递_[Java] 参数的传递:值传递与引用传递讨论

1.基本概念

首先要搞清楚一个概念,即:变量中储存的内容是什么。

变量类型分为基本数据类型和引用类型:

基本数据类型的变量直接存储的是变量的值,如int i=10;  i中存储的为变量的值。

引用类型的变量存储的则是实际对象的地址,如Dog myDog = new Dog();  myDog中存储的仅仅是地址(也可以称为引用)。

2.赋值操作

需要明确赋值操作的含义。

赋值操作“=”包含两个意思:1.放弃了原有的值或引用;2.得到了 = 右侧变量的值或引用。

基本类型:= 操作代表完整复制了变量的值。例如:int a=b;  a仅获取了b的值,两者在此之后并无任何关系。

引用类型:= 操作代表复制了变量的引用。 例如:Dog aDog=bDog;  aDog复制了bDog的引用,两个变量都指向同一个Dog对象。

一个简单的例子:

public class Test {

public static void main(String[] args) {

int x=10;

int y=x;

x=20;

System.out.println("x:"+x);

System.out.println("y:"+y);

Dog aDog=new Dog();

aDog.name="阿黄";

aDog.age=1;

Dog bDog=aDog;

aDog.name="旺财";//改变aDog的名字

bDog.age=2;//改变bDog的年龄

System.out.println("aDog:"+aDog.name+","+aDog.age);

System.out.println("bDog:"+bDog.name+","+bDog.age);

}

}

class Dog {

String name;

int age;

}

jia.gif

jian.gif

x:20y:10aDog:旺财,2bDog:旺财,2

输出结果

由结果可以看出,对于基本数据类型,在y=x后,y仅仅是获得了x的值,两者不再有关系了,因此输出结果不同;

对于引用类型,在bDog=aDog后,bDog获取了aDog的地址,两个变量都是指的同一条狗。虽然分别变化了aDog的名字和bDog的年龄,但其实变的都是同一个对象,所以输出结果相同。

3.参数传递

方法中参数传递的本质即为赋值操作。

/*第一个例子:基本类型*/

void foo(int value) {

value = 100;

}

foo(num); // num 没有被改变

例一分析:参数传递,相当于执行了value=num,value获得了num的值,这之后value与num无关,所以num没有改变。

/*第二个例子:没有提供改变自身方法的引用类型*/

void foo(String text) {

text = "windows";

}

foo(str); // str 也没有被改变

例二分析:参数传递后,text与str都存储了相同的地址,指向同一个对象;但之后text重新进行了赋值操作text= "windows",text放弃了原有的引用而指向了新的对象(见上述赋值操作的两重意思),而str仍为原有的引用,所以str没有改变。

/*第三个例子:提供了改变自身方法的引用类型*/

StringBuilder sb = new StringBuilder("iphone");

void foo(StringBuilder builder) {

builder.append("4");

}

foo(sb); // sb 被改变了,变成了"iphone4"。

例三分析:参数传递后,sb与builder指向同一个对象,builder.append()仅对该对象进行了增加操作,sb和builder仍指向同一对象,所以sb变为了"iphone4"。

参数传递后:

20180530175904972843.png

执行builder.append("4")后:

20180530175905031437.png

/*第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。*/

StringBuilder sb = new StringBuilder("iphone");

void foo(StringBuilder builder) {

builder = new StringBuilder("ipad");

}

foo(sb); // sb 没有被改变,还是 "iphone"。

例四分析:参数传递后,sb与builder指向同一个对象,但之后builder重新进行了赋值操作builder = new StringBuilder("ipad"),builder指向了一个新的对象,而sb仍为指向原来的对象,所以sb没有改变。

参数传递后:

20180530175905069523.png

执行builder = new StringBuilder("ipad")后:

20180530175905150578.png

4.值传递与引用传递讨论

在上述讨论中,可以知道,参数传递相当于赋值操作,

对于基本数据类型,方法中的形参获取了实参的值,即可以理解为值传递;

对于引用类型,方法中的形参获取的是实参的引用,两者指向同一对象,即可以理解为引用传递。

也有人认为,Java中的参数传递只有值传递,我觉得应该是把“引用传递”认为是引用的地址值的传递,所以统称为值传递。(知识还很浅薄,只是个人理解)

5.参考来源

《Head First Java》

主要参考的是这两个回答:1,2

本文内容是根据参考内容 结合自己的个人理解写的,如有错误,请多多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值