Получить класс компаньона в сопутствующем объекте

Есть ли способ получить 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.

kotlin,

2

Ответов: 1


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(что, на мой взгляд, не проблема и лучшее решение)

Котлин,
Похожие вопросы