【问题标题】:Do objects share the same memory address by default默认情况下对象是否共享相同的内存地址
【发布时间】:2019-05-26 22:31:33
【问题描述】:

这种行为是什么意思?

var string1 = "hello"
var string2 = "hello"
println(string1 == string2) // return true
println(string1 === string2) // return true

因为

平等:确定两个对象是否包含相同的状态。 (==)

identity:判断两个对象是否共享同一个内存地址。 (===)

它们共享相同的内存地址吗?

【问题讨论】:

    标签: kotlin object memory shared-memory equality


    【解决方案1】:

    简短的回答是YES,它们共享相同的内存地址。

    下一个描述适用于 Kotlin/JVM。当您声明一个新字符串时,幕后会发生一些有趣的事情。这是一个基本的字符串声明。我们创建一个名为string1 的新字符串变量并为其赋值:

    var string1 = "hello"
    

    它将在内存中为字面值hello分配空间。内存中的这个区域称为字符串常量池。它就像一个可供程序其他部分使用的字符串值池。 现在,如果您创建了另一个变量,例如 string2,并且还给它一个值 hello,Kotlin 会重新使用池中已经存在的值。 字符串常量池位于称为 heap 的一段内存中。这是用于运行时操作、处理类和对象的内存的一部分。把一堆想象成一块花园土壤,当你种植花园时,你可以很容易地从中取出泥土和植物。 Kotlin 将这些新对象放在那里。如果你再创建一百个对象,Kotlin 将在堆顶上再创建一百个字面量。

    我会使用引用相等(===)来检查变量是否指向同一个对象。

    【讨论】:

    • 这是对JVM的一个很好的描述;字符串常量折叠是 Java 规范的一部分,因此对于 Kotlin/JVM 来说必须如此。 ——但 Kotlin/JS 或 Kotlin/native 是否也能保证如此? (我想我会非常警惕任何以这种方式使用参照平等的程序。)
    • 没有检查,但这是一个很好的通知,除非您需要比较引用并检查它是否是是否相同的对象。
    【解决方案2】:

    我为你的好问题做了一些调查。

    与Kotlin's Reference 一样,基本类型在== 和=== 中的处理方式相同。

    但对于自定义对象,它们以不同的方式工作。 == 比较结构,=== 检查引用。

        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)
    

    【讨论】:

      【解决方案3】:

      是的,它们共享相同的内存地址。如果我们已经有“hello”,则不会创建新的“hello”

      var string2 = "hello"
      

      如果你通过构造函数创建了新字符串

      var string2 = String("hello")
      

      然后

      println(string1 === string2)
      

      返回错误

      阅读 Java 字符串池https://www.baeldung.com/java-string-pool

      【讨论】:

        猜你喜欢
        • 2019-06-17
        • 1970-01-01
        • 2012-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-01
        • 2017-02-01
        相关资源
        最近更新 更多