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
.
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.
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.
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.
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.
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
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...
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.
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:
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
}
}
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With