我试图理解内联类的概念-它们是在运行时内联的单一属性的简单对象包装。
这意味着该类的实际初始化未在运行时发生
我正在尝试编写简单的测试,该测试将在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
是静态方法,仅检查null
的value
,并且box-impl
创建包装器对象。您可以看到
nameInlineClass
确实是String
-这意味着内联工作并且没有分配额外的对象。仅当您引用
nameInlineClass
而不是nameInlineClass.value
编译器时,才确定该对象需要表示形式并使用包装NameInlineClass
类“包装”该值。关于kotlin - JUnit测试中的Kotlin内联类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56308810/