crg*_*dos 7 inline kotlin kotlin-extension jvm-bytecode
我知道内联关键字的意思是避免调用功能的调用开销。但是我不知道扩展属性可以用于什么内联?
假设我们有两个名为foo的扩展属性,另一个带有名为bar的内联属性
val Any.foo : Long
get() = Date().time
inline val Any.bar : Long
get() = Date().time
Run Code Online (Sandbox Code Playgroud)
执行其中的任何一个,我们将期望的输出,即当前时间。
该文件的字节码如下:
val Any.foo : Long
get() = Date().time
inline val Any.bar : Long
get() = Date().time
Run Code Online (Sandbox Code Playgroud)
我们可以看到两者相似,但仅在以下几行不同:
foo提取:
LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
Run Code Online (Sandbox Code Playgroud)
酒吧摘录:
LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0
LOCALVARIABLE $i$f$getBar I L0 L2 1
MAXSTACK = 2
MAXLOCALS = 2
Run Code Online (Sandbox Code Playgroud)
我真的不明白这里发生了什么。有人可以指点我看一下它的行为,或java中的等效行为,或对此的一些用法吗?
编辑
给定编译器将替换内联属性的内容,可以方便地内联每个没有繁重操作的扩展属性。
谢谢
根据Kotlin的文档,
请注意,由于扩展实际上并未将成员插入类,因此扩展属性没有有效的方法来拥有backing field。
和也,
该
inline修饰符可以用于没有后备字段的属性的访问器。
如上所述,内联扩展属性没有后备字段。您可以将扩展属性视为一对静态的getter / setter,如下所示:
//In Kotlin
var Any.foo : Long
get() = Date().time
set(value) {
//Cannot access field here since extension property cannot have backing field
//Do something with `obj`
}
//In Java
public static long getFoo(Object obj) {
return new Date().getTime();
}
public static void setFoo(Object obj) {
//Do something with `obj`
}
Run Code Online (Sandbox Code Playgroud)
因此,内联属性意味着访问该属性时,getter / setter函数的代码将内联到调用站点中(与常规内联函数相同)。
//In Kotlin
val x = "".foo
val y = "".bar
//Generated code
val x = InlinedExtensionPropertyKt.getFoo("")
val y = Date().time
Run Code Online (Sandbox Code Playgroud)
对于您在问题中发布的字节码,对不起我无法解释正在发生的事情。但是您可以尝试查看以下代码的字节码:
fun get() {
val x = "".foo
val y = "".bar
}
Run Code Online (Sandbox Code Playgroud)
,其中"".foo将调用getter函数,但"".bar不会。
| 归档时间: |
|
| 查看次数: |
1249 次 |
| 最近记录: |