提问人:Reza Shoja 提问时间:12/29/2018 最后编辑:SergioReza Shoja 更新时间:12/24/2021 访问量:933
默认情况下,对象共享相同的内存地址
Do objects share the same memory address by default
问:
此行为意味着什么?
var string1 = "hello"
var string2 = "hello"
println(string1 == string2) // return true
println(string1 === string2) // return true
因为
相等:确定两个对象是否包含相同的状态。(==)
标识:确定两个对象是否共享相同的内存地址。(===)
它们是否共享相同的内存地址?
答:
1赞
Sergio
12/29/2018
#1
简短的回答是肯定的,它们共享相同的内存地址。
下一个描述适用于 Kotlin/JVM。当您声明一个新字符串时,幕后会发生一些有趣的事情。这是一个基本的字符串声明。我们创建一个新的字符串变量,并给它一个值:string1
var string1 = "hello"
它将在内存中为文本值 hello 分配空间。内存中的此区域称为字符串常量池。它就像一个字符串值池,可用于程序的其他部分。
现在,如果您创建了另一个变量,比如 ,并且还给它指定了 hello 值,Kotlin 会重用池中已有的值。
字符串常量池位于内存的一部分内,称为堆。这是内存的一部分,用于运行时操作,处理类和对象。把一堆想象成一片花园土壤,当你种植花园时,你可以很容易地从中取出泥土和植物。Kotlin 将这些新对象放在那里。如果您再创建一百个对象,Kotlin 将在堆上再创建一百个文本。string2
我将使用引用相等 (===) 来检查变量是否指向同一对象。
评论
0赞
gidds
12/29/2018
这是对 JVM 的一个很好的描述;字符串常量折叠是 Java 规范的一部分,因此对于 Kotlin/JVM 必须如此。— 但是,对于 Kotlin/JS 或 Kotlin/native 来说,它是否也是正确的?(我想我会非常警惕任何以这种方式使用引用相等的程序。
0赞
Sergio
12/29/2018
没有检查,但这是一个很好的通知,除非您需要比较引用并检查它是否是同一对象,否则我根本不会依赖引用相等。
0赞
Artem Botnev
12/29/2018
#2
是的,它们共享相同的内存地址。如果我们已经有 “hello”,则不会由
var string2 = "hello"
如果通过构造函数创建了新字符串
var string2 = String("hello")
然后
println(string1 === string2)
返回 false
阅读有关 Java 字符串池 https://www.baeldung.com/java-string-pool 的信息
0赞
Mayur Prajapati
12/29/2018
#3
我为你的好问题做了一些发现。
与 Kotlin 的参考一样,基元类型在两者中的处理方式相同。==
===
但对于自定义对象,它们的工作方式不同。 比较结构并检查引用。==
===
fun main(args: Array<String>) { val v1 = Temp("world") val v2 = Temp("world") println(v1 == v2)// true println(v1 === v2)// false } data class Temp(var val1: String)
评论