We have a huge list with implementation instances of a generic interface. Then we get an element of any type. With some filter logic we find the correct instance out of the list.
How can we invoke a method and pass the element?
interface Processor<T> {
fun process(element: T)
// [many more methods ...]
}
// ***** implementations *****
class StringProcessor : Processor<String> {
override fun process(element: String) {}
}
class IntProcessor : Processor<Int> {
override fun process(element: Int) {}
}
// 50+ implementations for different types
// ***** invocation logic *****
fun main() {
val allProcessors = listOf(StringProcessor(), IntProcessor()) // dynamically loaded
val elementToProcess = "Test"
val correctProcessor = allProcessors
.first { /* logic that element type matches processor type */ true }
correctProcessor.process(elementToProcess) // <-- how to invoke this method??
}
The only (really bad) solution we found was using reflection:
fun main() {
val allProcessors = listOf(StringProcessor(), IntProcessor()) // dynamically loaded
val elementToProcess = "Test"
val correctProcessor = allProcessors
.first { /* logic that element type matches processor type */ true }
// bad idea ... but works
val method = correctProcessor::class.java.getMethod("process", Any::class.java)
method.invoke(correctProcessor, elementToProcess)
}
How is it possible to invoke the method without reflection?