diff --git a/docs/java/basis/why-there-only-value-passing-in-java.md b/docs/java/basis/why-there-only-value-passing-in-java.md index a45e4b9980a..42a792807ed 100644 --- a/docs/java/basis/why-there-only-value-passing-in-java.md +++ b/docs/java/basis/why-there-only-value-passing-in-java.md @@ -14,8 +14,8 @@ tag: 方法的定义可能会用到 **参数**(有参的方法),参数在程序语言中分为: -- **实参(实际参数)** :用于传递给函数/方法的参数,必须有确定的值。 -- **形参(形式参数)** :用于定义函数/方法,接收实参,不需要有确定的值。 +- **实参(实际参数,Arguments)** :用于传递给函数/方法的参数,必须有确定的值。 +- **形参(形式参数,Parameters)** :用于定义函数/方法,接收实参,不需要有确定的值。 ```java String hello = "Hello!"; @@ -112,7 +112,7 @@ num2 = 20 实际上,并不是的,这里传递的还是值,不过,这个值是实参的地址罢了! -也就是说 `change` 方法的参数拷贝的是 `arr` (实参)的地址,因此,它和 `arr` 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。 +也就是说 `change` 方法的参数拷贝的是 `arr` (实参)的地址,因此,它和 `arr` 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。 为了更强有力地反驳 Java 对引用类型的参数采用的不是引用传递,我们再来看下面这个案例! @@ -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 + +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 中将实参传递给方法(或函数)的方式是 **值传递** : @@ -168,4 +209,6 @@ Java 中将实参传递给方法(或函数)的方式是 **值传递** : ## 参考 - 《Java 核心技术卷 Ⅰ》基础知识第十版第四章 4.5 小节 -- [Java 到底是值传递还是引用传递? - Hollis的回答 - 知乎](https://www.zhihu.com/question/31203609/answer/576030121) \ No newline at end of file +- [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/)