K.O*_*.Os 2 junit kotlin 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)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,该测试失败了,这使我assertEquals()想到一个问题:为什么在实际的未包装的String值期间不进行比较,而在实际的内联类(运行时应对其进行包装)中不进行比较?
您可能想做的是val name = nameInlineClass.value,但是我将尽力解释该错误。
见表示从文档(包括代码示例):
在生成的代码中,Kotlin编译器为每个内联类保留一个包装器。内联类实例可以在运行时表示为包装器或基础类型。这类似于将Int表示为原始int或包装Integer的方式。
这意味着只要您不显式引用包装对象或其类型,就不会将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");
}
Run Code Online (Sandbox Code Playgroud)
我不会粘贴整个生成的NameInlineClass主体,但它constructor-impl是仅检查nullof value并box-impl创建包装对象的静态方法。
您可以看到nameInlineClass确实是String-表示内联工作并且没有分配额外的对象。
仅当您引用nameInlineClass而不是nameInlineClass.value编译器时,才确定该对象需要表示形式并将值与包装器NameInlineClass类“装箱” 。
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |