gpt4 book ai didi

JUnit 测试中的 Kotlin 内联类

转载 作者:行者123 更新时间:2023-12-02 08:01:51 24 4
gpt4 key购买 nike

我试图理解内联类的概念——它们是单个属性的简单对象包装器,在运行时被内联。这意味着,类的实际初始化不会在运行时发生

我正在尝试编写简单的测试,它会在 JUnit 测试期间直接显示我的上述解释,如下所示:

companion object {
private const val NAME = "JACK"
}

inline class NameInlineClass(val value: String)

@Test
fun unwrapping() {
val nameInlineClass = NameInlineClass(NAME)
val name = nameInlineClass
assertEquals(name, NAME)
}

不幸的是,这个测试失败了,这让我想到了一个问题,为什么在 assertEquals() 期间没有比较实际解包的 String 值,而是比较实际的内联类(应该在运行时解包)?

最佳答案

您可能想要做的是 val name = nameInlineClass.value,但我会尝试解释错误。

参见 Representation来自文档(包括代码示例):

In generated code, the Kotlin compiler keeps a wrapper for each inline class. Inline class instances can be represented at runtime either as wrappers or as the underlying type. This is similar to how Int can be represented either as a primitive int or as the wrapper Integer.

这意味着只要您不显式引用包装对象或其类型,值就不会被装箱。我们可以通过检查字节码(为了可读性而反编译回 Java)来检查它:

// kotlin source
fun unwrapping() {
val nameInlineClass = NameInlineClass(NAME)
val name = nameInlineClass // this line gets dropped by compiler by the way
assertEquals(name, NAME)
}

// java representation of bytecode
public final void unwrapping() {
String nameInlineClass = NameInlineClass.constructor-impl("JACK");
Assert.assertEquals(NameInlineClass.box-impl(nameInlineClass), "JACK");
}

我不会粘贴整个生成的 NameInlineClass 主体,但是 constructor-impl 是静态方法,它只检查 null valuebox-impl 创建包装器对象。

您可以看到 nameInlineClass 确实是一个 String - 这意味着内联有效并且没有分配额外的对象。

仅当您引用 nameInlineClass 而不是 nameInlineClass.value 时,编译器才确定此对象需要表示,并使用包装器 NameInlineClass 将值“装箱”类。

关于JUnit 测试中的 Kotlin 内联类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56308810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com