[reflection] How to get companion object and new instance from ::class via reflection?

 

class A{
  companion object{
  fun fn(){
          println(“A”)
  }
  }
}

class B{
  companion object{
  fun fn(){
          println(“B”)
  }
  }
}

fun invokeFnInCompanion(cl : KClass<*>){
  //???
}

fun invokeCtor<T>(cl : KClass<T>):T{
  //???
}

invokeFnInCompanion(A::class) // must print A
invokeFnInCompanion(B::class) // must print B
invokeCtor(A::class) // must return new instance A
invokeCtor(B::class) // must return new instance B


How to write body of invokeFnInCompanion?
How to write body of invokeCtor?

Companion object is a named object whose name is Companion. So, this will get a class reference to the companion object: A.Companion::class. In the same fashion, to get a function reference to fn you can write A.Companion::fn. New instance construction is not yet supported in Kotlin reflection.

can anyone please let me know any updates on this issue ?

I tried with companionObjectInstance

getCompanionObjectFromReflexiveApi() {

val companionObjectJavaClass = Utils.Companion::class.java

    val companionObjectInstance = companionObjectJavaClass.kotlin
        .companionObjectInstance!!
    val result: Boolean = companionObjectInstance::class.java
        .methods
        .first { it.name == "comapanionObjectMethod" }
        .invoke(companionObjectInstance, context, "hello") as Boolean

   val companionClass = Class.forName("com.xyz.common.Utils\${Companion}")
    val checkReflexiveMethod: Method = companionClass.getDeclaredMethod(
        "comapanionObjectMethod", Context::class.java,
        String::class.java
    )

}

getting error as java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/reflect/full/KClasses;

in gradle used the plugin implementation “org.jetbrains.kotlin:kotlin-reflect:$1.6.21”

The most naive version could look like this:

fun invokeFnInCompanion(cls: KClass<*>) {
	cls.companionObject!!.functions.first { it.name == "fn" }.call(cls.companionObjectInstance)
}

fun <T : Any> invokeCtor(cls: KClass<T>): T {
	return cls.primaryConstructor!!.call()
}

Thank you for your reply @ madmax1028

I have used your code in my test cases

still I’m getting the below error

Caused by: java.lang.ClassNotFoundException: Didn’t find class “kotlin.reflect.full.KClasses” on path: DexPathList[[zip file “/system/framework/android.test.runner.jar”, zip file “/system/framework/android.test.mock.jar”, zip file “/system/framework/android.test.base.jar”, zip file

It looks like kotlin-reflect library is not available. Indicates some problem with your gradle configuration most likely.

I have used this plugin in build.gradle

implementation “org.jetbrains.kotlin:kotlin-reflect:$1.6.21”

Why did you put a $ sign in the first place? When I tried it locally a dependency simply dissapeared from my classpath. Try to remove it for starters:

implementation "org.jetbrains.kotlin:kotlin-reflect:1.6.21"

please excuse that, its typo mistake I have kept kotlin_version variable at project level build.gradle file

and I configured in app’s build.gradle like
implementation “org.jetbrains.kotlin:kotlin-reflect:$kotlin_version”

can you please help me

From your previous posts I guess that we are talking about an Android application here. Unfortunatelly it’s not my area of expertise :slight_smile:

1 Like

Use ./gradlew dependencies to get a dependency tree, and see if the Kotlin reflect library is in your dependencies.