Skip to content

Commit

Permalink
Update why-there-only-value-passing-in-java.md
Browse files Browse the repository at this point in the history
  • Loading branch information
samho2008 committed Oct 21, 2022
1 parent 4b3e312 commit 6acab4e
Showing 1 changed file with 47 additions and 4 deletions.
51 changes: 47 additions & 4 deletions docs/java/basis/why-there-only-value-passing-in-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ tag:

方法的定义可能会用到 **参数**(有参的方法),参数在程序语言中分为:

- **实参(实际参数)** :用于传递给函数/方法的参数,必须有确定的值。
- **形参(形式参数)** :用于定义函数/方法,接收实参,不需要有确定的值。
- **实参(实际参数,Arguments** :用于传递给函数/方法的参数,必须有确定的值。
- **形参(形式参数,Parameters** :用于定义函数/方法,接收实参,不需要有确定的值。

```java
String hello = "Hello!";
Expand Down Expand Up @@ -112,7 +112,7 @@ num2 = 20

实际上,并不是的,这里传递的还是值,不过,这个值是实参的地址罢了!

也就是说 `change` 方法的参数拷贝的是 `arr` (实参)的地址,因此,它和 `arr` 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。
也就是说 `change` 方法的参数拷贝的是 `arr` (实参)的地址,因此,它和 `arr` 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。

为了更强有力地反驳 Java 对引用类型的参数采用的不是引用传递,我们再来看下面这个案例!

Expand Down Expand Up @@ -158,6 +158,47 @@ xiaoLi:小李

![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/java-value-passing-03.png)

## 引用传递是怎么样的?

看到这里,相信你已经知道了 Java 中只有值传递,是没有引用传递的。
但是,引用传递到底长什么样呢?下面以 `C++` 的代码为例,让你看一下引用传递的庐山真面目。

```C++
#include <iostream>

void incr(int& num)
{
std::cout << "incr before: " << num << "\n";
num++;
std::cout << "incr after: " << num << "\n";
}

int main()
{
int age = 10;
std::cout << "invoke before: " << age << "\n";
incr(age);
std::cout << "invoke after: " << age << "\n";
}
```
输出结果:
```
invoke before: 10
incr before: 10
incr after: 11
invoke after: 11
```
分析:可以看到,在 `incr` 函数中对形参的修改,可以影响到实参的值。要注意:这里的 `incr` 形参的数据类型用的是 `int&` 才为引用传递,如果是用 `int` 的话还是值传递哦!
## 为什么 Java 不引入引用传递呢?
引用传递看似很好,能在方法内就直接把实参的值修改了,但是,为什么 Java 不引入引用传递呢?
**注意:以下为个人观点看法,并非来自于 Java 官方:**
1. 出于安全考虑,方法内部对值进行的操作,对于调用者都是未知的(把方法定义为接口,调用方不关心具体实现)。你也想象一下,如果拿着银行卡去取钱,取的是 100,扣的是 200,是不是很可怕。
2. Java 之父 James Gosling 在设计之处就看到了 C、C++ 的许多弊端,所以才想着去设计一门新的语言 Java。在他设计 Java 的时候就遵循了简单易用的原则,摒弃了许多开发者一不留意就会造成问题的“特性”,语言本身的东西少了,开发者要学习的东西也少了。
## 总结
Java 中将实参传递给方法(或函数)的方式是 **值传递** :
Expand All @@ -168,4 +209,6 @@ Java 中将实参传递给方法(或函数)的方式是 **值传递** :
## 参考
- 《Java 核心技术卷 Ⅰ》基础知识第十版第四章 4.5 小节
- [Java 到底是值传递还是引用传递? - Hollis的回答 - 知乎](https://www.zhihu.com/question/31203609/answer/576030121)
- [Java 到底是值传递还是引用传递? - Hollis的回答 - 知乎](https://www.zhihu.com/question/31203609/answer/576030121)
- [Oracle Java Tutorials - Passing Information to a Method or a Constructor](https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html)
- [Interview with James Gosling, Father of Java](https://mappingthejourney.com/single-post/2017/06/29/episode-3-interview-with-james-gosling-father-of-java/)

0 comments on commit 6acab4e

Please sign in to comment.