gpt4 book ai didi

kotlin - 如何使用 Kotlin KClass 属性 simpleName 生成空值

转载 作者:行者123 更新时间:2023-12-02 11:48:26 24 4
gpt4 key购买 nike

KClass.simpleName 的规范在 Kotlin 1.3.41 for Common、JS、JVM 和 Native 上是:

The simple name of the class as it was declared in the source code, or null if the class has no name (if, for example, it is an anonymous object literal).



生成 null 似乎很简单:获取从匿名对象文字生成的 KClass 的 simpleName。下面的代码是一个失败的尝试:
interface Human { fun think(): String }

@Test fun `when finding the name of an anonymous object verify the name is null`() {
fun start(man: Human) = println(man.think())

start(object: Human {
val name = this::class.simpleName
override fun think() = "Thinking really hard! Name is: $name" // name == 2
})
}

我的期望是名字应该是 null .为什么名称为 2 的值?我应该如何更改代码以使 name 的值为 null ?

最佳答案

我稍微改变了你的代码:

interface Human { fun think(): String }

fun main() {

fun start(man: Human) = println(man.think())

start(object: Human {
val name = this::class.java.simpleName
override fun think() = "Thinking really hard! Name is: $name" // name == 2
})
}

Why is the value of name 2?


现在让我们看看这个字节码。
这是 start 的字节码的一部分功能。如您所见,它实现了 Function0它有一个 invoke采用 Human 的方法.
final class com/example/customview/TestKt$main$1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {


// access flags 0x1041
public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
ALOAD 0
ALOAD 1
CHECKCAST com/example/customview/Human
INVOKEVIRTUAL com/example/customview/TestKt$main$1.invoke (Lcom/example/customview/Human;)V
GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
ARETURN
MAXSTACK = 2
MAXLOCALS = 2

// access flags 0x11
public final invoke(Lcom/example/customview/Human;)V

....

这是匿名对象字节码的一部分,如您所见,它实现了 Human :
public final class com/example/customview/TestKt$main$2 implements com/example/customview/Human {

OUTERCLASS com/example/customview/TestKt main ()V

// access flags 0x12
private final Ljava/lang/String; name

.....

你可以从字节码中看到你的匿名类的名字实际上是 TestKt$main$2 .因为编译器会自动为您的文件生成一个类 TestKt和另一个主函数类 TestKt$Main .然后对于每个函数或匿名类,将生成另一个类,并按顺序命名它们。例如,这里的函数 start有一个名为 TestKt$main$1 的类扩展 LambdaFunction0 .
如果您在主函数中添加一个虚拟方法,如下所示:
fun main() {

fun start(man: Human) = println(man.think())

fun nothing() = {}

start(object: Human {
val name = this::class.java.simpleName
override fun think() = "Thinking really hard! Name is: $name" // name == 3 this time
})
}
那么你的类(class)名称将是 3这就是为什么它是 2 的答案

How should I change the code to get the value of the name to be null?


您可以使用 qualifiedName而不是 simpleName .这一定是文档中的错误,只需忽略括号中的部分,即“例如,如果它是匿名对象文字”。
这是文档中关于qualifiedName 的说明:

The fully qualified dot-separated name of the class, or null if the class is local or a class of an anonymous object.


它像它所说的那样工作。
start(object: Human {
val name = this::class.qualifiedName
override fun think() = "Thinking really hard! Name is: $name" // name == null
})

关于kotlin - 如何使用 Kotlin KClass 属性 simpleName 生成空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57229715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com