Search code examples
kotlinreflection

How to get getDeclaredMethod in Generic type class?(Kotlin Reflection)


How to get getDeclaredMethod in Generic type class by Kotlin Reflection

i declared generic type class

class ForReflectionTest<T>(val data:T=null) : SuperTester<T>{
    fun init(data2: T?){
    }
}

and i want access it by reflection. this class create so many instances (over 30+, or maximum over 500+) and every instance has different type of Data.

and this instances managed in list<ForReflectionTest>

but when i try getDeclaredMethod(), android throw java.lang.NoSuchMethodException: com.my.test.ForReflectionTest.init [class java.lang.String]

how can i solve it?

i tried like this (call side)

for(i:ForReflectionTest<*> in instanceList){
    val method: Method = i.javaClass.getDeclaredMethod("init", Any::class.java) // Error! NoSuchMethod
    method.invoke(i, null)
}

and other try. (data is nullable)

val method: Method = i.javaClass.getDeclaredMethod("init", if(i.data != null)i.data::class.java else Unit::class.java)) // Error! NoSuchMethod

i create var i = i:ForReflectionTest<String>() and i try like this, i.javaClass.getDeclaredMethod(i.data::class.java) it occur error NoSuchMothod. but why? isn't created init method has String type Parameter in compile time?

when i remove generic and try like this, is Successful!

class ForReflectionTest(val data:String?=null) : SuperTester<String>{
    fun init(data2: String?){
    }
}

call side

var i = i:ForReflectionTest()
i.javaClass.getDeclaredMethod("init", String::class.java)

Solution

  • You could use Kotlin reflection instead of the Java reflection.

    Then you can just write:

    val method = i::class.declaredFunctions.first { it.name == "init" }
    method.call(i, null /* or whatever data you want to use as argument */)
    

    If you want to call the init function with the data value of your i element, you can just call method.call(i, i.data).