有没有办法在不知道它的名字的情况下将伴侣类的javaClass
放在伴侣对象中?
我想我可以通过这样的方式得到它:
open class TestClass {
companion object {
init {
val clazz = Class.forName(this::class.java.canonicalName.removeSuffix(".Companion"))
}
}
}
但是,这对class InheritingClass : TestClass()
不起作用。它仍然会给我TestClass,而不是InheritingClass。
我希望能像this::class.companionClass
那样更加直截了当。
答案 0 :(得分:1)
伴侣类本身没有引用实际的类,正如您在此字节码中所看到的那样
public final class TestClass$Companion {
private TestClass$Companion() { // <init> //()V
<localVar:index=0 , name=this , desc=LTestClass$Companion;, sig=null, start=L1, end=L2>
L1 {
aload0 // reference to self
invokespecial java/lang/Object <init>(()V);
return
}
L2 {
}
}
public TestClass$Companion(kotlin.jvm.internal.DefaultConstructorMarker arg0) { // <init> //(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
<localVar:index=0 , name=this , desc=LTestClass$Companion;, sig=null, start=L1, end=L2>
<localVar:index=1 , name=$constructor_marker , desc=Lkotlin/jvm/internal/DefaultConstructorMarker;, sig=null, start=L1, end=L2>
L1 {
aload0 // reference to self
invokespecial TestClass$Companion <init>(()V);
return
}
L2 {
}
}
}
引用只是反过来(参见反编译的kotlin类)
public final class TestClass {
public static final Companion companion = ...
}
所以你可以像你刚才那样通过切断班级名称的.Companion
部分来做,或者用TestClass::class.java
努力引用它(我认为没什么问题和最好的)溶液)
答案 1 :(得分:0)
为了获得另一个类的伴随对象的类,您将最终只使用以下内容:
TestClass::class.companionObject
这是一个例子:
class TestClass {
companion object {
fun sayHello() = "Hello world"
}
}
// Whenever you want to know the companion of TestClass
TestClass::class.companionObject // It'll return TestClass.Companion
如果您想获取包含同伴的类,因为后者始终是前者的内部类,因此您将得出以下结论:
class TestClass {
companion object {
fun whichIsMyParentClass() = this::class.java.declaringClass // It'll return TestClass
}
}
为简化起见,您还可以使用以下代码创建扩展属性:
import kotlin.reflect.KClass
val <T : Any> KClass<T>.companionClass get() = if (isCompanion) this.java.declaringClass else null
现在,每当要获取伴随对象的父类时,只需查看以下示例:
class TestClass {
companion object {
fun whichIsMyParentClass() = this::class.companionClass // It'll return TestClass
}
}
答案 2 :(得分:0)
如果需要打印类名,可以加上simpleName,如
this::class.java.declaringClass.simpleName