Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get companion class in companion object

Tags:

kotlin

Is there a way to get the javaClass of the companion class inside a companion object without knowing it's name?

I suppose I could get it by doing something like this:

open class TestClass {
    companion object {
        init {
            val clazz = Class.forName(this::class.java.canonicalName.removeSuffix(".Companion"))
        }
    }    
}

However, this does not work for class InheritingClass : TestClass(). It would still give me TestClass, not InheritingClass.

I was hoping for something more straightforward like this::class.companionClass.

like image 986
shutefan Avatar asked Jul 06 '17 11:07

shutefan


People also ask

How do you use companion objects?

To create a companion object, you need to add the companion keyword in front of the object declaration. The output of the above code is “ You are calling me :) ” This is all about the companion object in Kotlin. Hope you liked the blog and will use the concept of companion in your Android application.

When should I use companion object?

companion object for factory functions Notice how the constructor is kept private but the companion object has access to the constructor . This is useful when you want to provide multiple ways to create an object where the object construction process is complex.

How do you use companion objects in Java?

Declaring a companion object If we declare the object inside a class, we have an option to mark it as a companion object. In terms of Java, the members of the companion object can be accessed as static members of the class. Marking an object as a companion allows us to omit the object's name while calling its members.

Can data class have companion object?

Now it's possible for companion object. Note that the data class does not implement the interface, but its companion object does. 2- you can define extension functions on it. you can call these extension functions as functions on class name.

What is a companion class?

We’ll dive into case classes in the next lesson. A companion object is an object that’s declared in the same file as a class, and has the same name as the class A companion object and its class can access each other’s private members A companion object’s apply method lets you create new instances of a class without using the new keyword

What is a companion object in Java?

The key points of this lesson are: 1 A companion object is an object that’s declared in the same file as a class, and has the same name as the class 2 A companion object and its class can access each other’s private members 3 A companion object’s apply method lets you create new instances of a class without using the new keyword More items...

How to declare a companion object inside an existing class?

The companion object can be declared within an existing class and the functions or parameters can be defined inside the companion object declaration. As you can see above, we can declare a companion object inside an existing class. We can also have an explicit name for the companion object that’s declared for enhanced readability.

What is a companion object in Scala?

This page has a new version. A companion object in Scala is an object that’s declared in the same file as a class, and has the same name as the class. For instance, when the following code is saved in a file named Pizza.scala, the Pizza object is considered to be a companion object to the Pizza class:


2 Answers

Getting the class of the companion object of a given class will look like this:

TestClass::class.companionObject

Here's an example:

class TestClass {

    companion object {
        fun sayHello() = "Hello world"
    }
}

If you want to get the class that contains the companion, since the latter is always an inner class of the former,

class TestClass {

    companion object {
        fun whichIsMyParentClass() = this::class.java.declaringClass // It'll return TestClass
    }
}

And to further simplify, you'll also want to create an extension property:

import kotlin.reflect.KClass

val <T : Any> KClass<T>.companionClass get() =
    if (isCompanion)
        this.java.declaringClass
    else
        null

So, whenever you want to get the parent class of the companion object,

class TestClass {

    companion object {
        fun whichIsMyParentClass() = this::class.companionClass // It'll return TestClass
    }
}
like image 172
Davide Cannizzo Avatar answered Sep 28 '22 19:09

Davide Cannizzo


The companion class itself has no reference to the actual class as you can see in this bytecode

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 {
         }
     }
}

The reference is only the other way around (see decompiled kotlin class)

public final class TestClass {
    public static final Companion companion = ...
}

So you can either do it as you just did by cutting off the .Companion part of the class name or you reference it by hard with TestClass::class.java (what is in my opinion no problem and the best solution)

like image 32
guenhter Avatar answered Sep 28 '22 19:09

guenhter