我试图理解内联类的概念-它们是在运行时内联的单一属性的简单对象包装。
这意味着该类的实际初始化未在运行时发生

我正在尝试编写简单的测试,该测试将在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,但是我将尝试解释该错误。

请参阅docs中的Representation(包括代码示例):



这意味着只要您不显式引用包装对象或其类型,就不会将value装箱。我们可以通过检查字节码(将其反编译为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是静态方法,仅检查nullvalue,并且box-impl创建包装器对象。

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

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

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

10-12 04:02