Search code examples
javaandroidkotlinreflectioncompanion-object

How get companion method reference (KFunction<>) by refelection


In Java it is possible to get a reference to static method in the following way (using reflection):

Method method = Class.forName("java.util.HashMap").getMethod("put", Object.class, Object.class);

In Kotlin it is possible to get a reference (type KFunctionX<>) to instance method in the following way (using reflection):

    var methodRef : KFunction0<Unit> = someInatance::instanceMethod

But when trying to get a companion method (using reflection) in the following way:

    var companionMethod = SomeJavaClass::someCompanionMethod

I'm getting an unresolved reference error


Solution

  • As the docs suggest, when you don't provide a name to the companion object (unnamed companion), it gets Companion by default.

    So the following should work fine:

    val companionMethod = SomeKotlinClass.Companion::someCompanionMethod
    

    And if you name your companion object, you can reference it with its name:

    class SomeKotlinClass {
        companion object Named {
            fun someCompanionMethod() {...}
        }
    }
    
    val companionMethod = SomeKotlinClass.Named::someCompanionMethod
    

    Edit:

    As the OP is still confused why SomeKotlinClass::someCompanionMethod does not work. Here's the explaination:

    You can still reference the companion with .Companion when you are calling the functions from it as well, like SomeKotlinClass.Companion.someCompanionMethod(...).

    // This works :)
    val s = SomeKotlinClass
    val companionMethod = s::testFunction
    
    // but this doesn't :(
    val companionMethod = SomeKotlinClass::testFunction
    

    Well, its because the :: does not resolve companion.

    Why? Because it will be ambiguous if it will, as function of same name can be defined in both companion and class, it won't be able to differentiate between them.

    But at call-site compiler can differentiate between member and companion calls, as you call companion as SomeKotlinClass.testFunction() and member on its instance: instanceOfSomeKotlinClass.testFunction().