JUnit 测试中的 Kotlin 内联类

标签 kotlin junit kotlin-experimental kotlin-inline-class

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

我正在尝试编写简单的测试,它会在 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/

相关文章:

kotlin - 为什么 UInt 没有 toDouble()?

java - Eclipse 未找到类定义 - Loadrunner lr.class

android - 将 Kotlin 内联类作为实体字段的房间数据库

android - 如何在 Android 中突出显示设置行?

android - 如何使用 Koin 管理用户范围?

android - 如何在 retrofit 多部分请求中发送对象数组

java - Spring MVC - 使用 Flyway 在测试之间清理数据库

java - 如何设置 Ant 'junit' 任务的工作目录?

android-studio - 如何在项目范围内使用 Kotlin 实验性无符号类型 (Android Studio)