值传递、关于求值策略中传值调用(call by value)、传引用调用(call by reference)、传地址调用(call by address)、传共享对象调用(call by sharing)

1815 2020-12-31 10:17

问题来源:《Java工程师成神之路(基础篇)》

求值策略(Evaluation strategy)是确定编程语言中表达式的求值的一组规则。给出一个函数,给出函数的参数、次序,然后获得结果。

parameter=形参(formal parameter),
argument=实参(actual parameter)

而将实际参数的值拷贝一份扔进函数对应的形式参数,还是直接把本尊扔进去。就体现了传值还是传引用。

而传引用往往都是通过引用(引用其他对象的对象),比如指针(表示其他对象的内存地址的对象)来模拟。但是里面又出现了一个特例,叫做共享对象引用,它是类型安全和内存安全的。

所以java和python都选择了传共享对象调用。

也可以说,java是传值引用(基本数据类型),而对于对象,java传递的值,是对象的引用。所以可以达到调用者看到共享对象中的内容改变了。

 

举个简单的例子:created by Gorsche 21

一列车的车厢,里面拉着货物

你要提取货物,那么就要找到这个车厢的车厢号和对应的门牌号,也就是车票。

那么如果拉的货物,本身就是一张车票。

那么你获取的 是个什么?

是一个求值策略。如果你的求值策略只管内容而不管引用。那么你是不可能通过拉的信息,去找到引用的信息的。你只能得到一串字符返回。

值传递也好、共享对象传递也好。在java里,如果设计一个函数,就是在游戏里打副本(下载回来自己打自己的)。副本传递造成的结果就是将二级指针调用化作了迭代的函数调用。这样就没有了多层梦境。反而像尾递归转循环一样。更加安全牢靠。

 

求值、拷贝、传递这三大步骤,共享对象调用和传值调用的过程几乎是一样的。

值传递测试的两个源代码

 

 

以下源自《Java工程师成神之路(基础篇)》。

基础类型: 很多人说 Java 中的基本数据类型是值传递的, 这个基本没有什么可以讨论的, 普遍都是这样认为的。

Java中的对象: Java 对象的传递, 是通过复制的方式把引用关系传递了, 如果我们没有改引用关系, 而是找到引用的地址, 把里面的内容改了, 是会对调用方有影响的, 因为大家指向的是同一个共享对象。

在程序设计中, 求值策略有很多种, 比较常见的就是值传递和引用传递。 还有一种值传递的特例——共享对象传递。

值传递和引用传递最大的区别是传递的过程中有没有复制出一个副本来, 如果是传递副本, 那就是值传递, 否则就是引用传递。

在 Java 中, 其实是通过值传递实现的参数传递, 只不过对于 Java 对象的传递, 传递的内容是对象的引用。

我们可以总结说, Java 中的求值策略是共享对象传递, 这是完全正确的。

但是, 为了让大家都能理解你说的, 我们说 Java 中只有值传递, 只不过传递的内容是对象的引用。 这也是没毛病的。

但是, 绝对不能认为 Java 中有引用传递。

以上——源自《Java工程师成神之路(基础篇)》。

 

简单说成传值、传引用,那都是C语言级别的,高级语言应该上升一个层面来说,那么就新定义一个对象的概念,并且是共享对象,因为里面有可变对象和不可变对象,这样那种用简单思维来下定义、归类的人就无法指证说法的错误了,因为他们压根儿不理解新概念,如果理解了,也就不会再用低级语言的形式来归类高级语言的概念了。


21个人总结,java的对象参数传递是对象引用的值(副本)传递!!!python的求值策略和java相同。python的字符串常量池

全部评论

·