在随播对象中获取伴侣类

时间:2017-07-06 11:08:26

标签: kotlin

有没有办法在不知道它的名字的情况下将伴侣类的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那样更加直截了当。

3 个答案:

答案 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