为什么说 Java 中只有值传递

259 阅读3分钟

首先,我们得首先知道什么是“值传递”和“引用传递”。

 值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

 引用传递(pass by reference):是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

那么,知道这些概念之后,我们就可以来通过代码来理解这些问题了。

第一步

代码如下:

结果为:

从当前的代码来看,发现实际参数并没有发现变化,那么我们就说是值传递了,但是仅仅是这样简单吗?先不用急着下结论,来看看第二步吧。

第二步:

代码如下

结果为:

在这里,我们发现,两次打印出来的对象居然是一样的!实际参数居然改变了!于是这个时候,就立刻有人来说了,java中的不是值传递,是引用传递。

可是,真的是这样吗?

这个时候,我们需要回过头来看看引用传递的定义了!

引用传递(pass by reference):是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

我们需要仔细理解一下这句话,它的意思是将实际参数的地址(这个地址,也就是我们说的引用,hash值)传递到函数中,那么在函数中对实际参数所进行的修改,将影响到实际参数。

所以,在本次的这个例子中,你既然修改的不是你传递进去的参数(也就是我们说的引用),你修改的是传递进去的引用所指向的对象本身,那么肯定就会出现对象的变化。

从一开始,你就没有对你传递进去的参数进行修改!所以,这个例子本身就举错了。

那么,怎么才是对传递进去的参数进行修改呢?请看第三步!

第三步:

代码如下:

结果如下:

真正修改了传递进去的参数(也就是引用的),是下面这段代码。

       user=new User();

而从代码运行的结果可以看出,实际参数并没有变化。

也就是说,我们在函数中对参数进行的修改,并没有影响到实际参数。

那么,从这里开始,我们可以说是值传递了。这个时候我们可以再看一个例子。

第四步:

代码如下:

答案如下:

我们发现,这里我们同样传递的是对象,但是而且也是对参数所指向的对象进行修改,但是居然没有影响到实际参数。这和我们的第二步居然不一样。

这里,我们必须要了解到一件事情,String类型的对象的修改,是和其他基础类型是不一致的。String类型永不可变。也就是说,在代码

 a="你";

中,实际的情况是这样的,因为java中存在字符串常量池,当我们发现常量池中发现没有“你”这个字符串的时候,那么我们将会生成一个新的对象返回。

也就是说,实际上也是对传递进去的引用进行了修改,但是,也没有影响到实际参数。所以,并不是引用传递。

结论:

java中只有值传递,没有引用传递。