kotlin - Kotlin 是 "pass-by-value"还是 "pass-by-reference"?

标签 kotlin

据我所知,Java 是来自 this post 的值传递.我来自 Java 背景,我想知道 Kotlin 使用什么来在两者之间传递值。喜欢 ExtensionsMethods等等

最佳答案

每次我听到关于“按值传递”与“按引用传递”Java 辩论时,我总是这么想。我给出的答案是:“Java 传递引用(按引用传递)的副本(按值传递)”。所以大家都很开心。我会说 Kotlin 的功能与基于 JVM 的语言相同。

更新

好的,距离这个答案已经有一段时间了,我认为应该包括一些澄清。正如@robert-liberatore 在评论中提到的那样,我所描述的行为是真实的对象。每当您的方法需要任何对象时,您都可以假设 JVM 在内部将复制对该对象的引用并将其传递给您的方法。这就是为什么有这样的代码

void doSomething(List<Integer> x) {
  x = new ArrayList<Integer>()
}

List<Integer> x = Arrays.asList(1, 2, 3);
doSomething(x);
x.length() == 3

表现得像它一样。您正在复制对列表的引用,因此“重新分配它”对真实对象无效。但是由于您指的是同一个对象,因此修改其内部内容会影响外部对象。

在将属性定义为 final 以实现不变性时,您可能会忽略这一点。您将无法重新分配它们,但没有什么可以阻止您更改其内容

当然,对于您有引用的对象也是如此。在原语的情况下,它不是对包含某物的对象的引用,而是“某物”本身,那么事情就不同了。 Java 仍然会复制整个值(就像它对整个引用所做的那样)并将其传递给方法。但是原语只是值,您不能“修改其内部值”。因此,方法内部的任何更改都不会影响外部值

现在,谈谈 Kotlin

在 Kotlin 中,您“没有”原始值。但是你“确实有”原始类。在内部,编译器将在需要时尝试使用 JVM 原语值,但您可以假设您始终使用 JVM 原语的盒装版本。因此,在可能的情况下,编译器只会复制原始值,而在其他情况下,它将复制对对象的引用。或者用代码

fun aJvmPrimitiveWillBeUsedHere(x: Int): Int = x * 2

fun aJvmObjectWillBeUsedHere(x: Int?): Int = if (x != null) x * 2 else 1

我会说 Kotlin 场景比 Java 更安全,因为它强制它的参数是最终的。所以你可以修改它的内部内容,但不能重新分配它

fun doSomething(x: MutableList<Int>) {
    x.add(2)                  // this works, you can modify the inner state
    x = mutableListOf(1, 2)   // this doesn't work, you can't reassign an argument
}

关于kotlin - Kotlin 是 "pass-by-value"还是 "pass-by-reference"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44515031/

相关文章:

gradle - 如何使 compileKotlin 依赖于 compileJava in gradle

kotlin - 如何在 Kotlin 中设置自定义返回类型可为空

android - 无法在 Android 上加载 svg 资源

arrays - 使用 spring-restdocs 记录数组的每个元素

kotlin - 标记函数暂停或使用构建器

android - Kotlin 协程使用 runBlocking 进行单元测试不等待执行

java - 正则表达式检测字符是否重复超过三次

kotlin - 如何使 "inappropriate blocking method call"合适?

arrays - 尝试找到Kotlin数组中的最低数字

android - 如何在 Android ViewModel 中等待多个作业?