Skip to content

Instantly share code, notes, and snippets.

@yijunwu
Forked from mikehearn/KotlinDuckTyping.kt
Last active May 29, 2018 06:32
Show Gist options
  • Save yijunwu/c2fab77c003e892b2b8c6c20304a3fd7 to your computer and use it in GitHub Desktop.
Save yijunwu/c2fab77c003e892b2b8c6c20304a3fd7 to your computer and use it in GitHub Desktop.
Kotlin duck typing / type classing fiddle
import java.lang.reflect.*
import java.util.*
class A {
fun shout() = println("go team A!")
}
class B {
fun shout() = println("go team B!")
}
interface Shoutable {
fun shout()
}
class InvokeHandler(private val underlying: Any) : InvocationHandler {
override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
for (fn in underlying.javaClass.methods) {
if (fn.name == method.name && Arrays.equals(fn.parameterTypes, method.parameterTypes)) {
if (args == null)
return fn.invoke(underlying)
else
return fn.invoke(underlying, *args)
}
}
throw UnsupportedOperationException("$method with $args")
}
}
inline fun <reified T> Any.dynamicCast(): T {
return Proxy.newProxyInstance(javaClass.classLoader, arrayOf(T::class.java), InvokeHandler(this)) as T
}
fun main(args: Array<String>) {
val a = A()
val b = B()
val sa = a.dynamicCast<Shoutable>()
val sb = b.dynamicCast<Shoutable>()
sa.shout()
sb.shout()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment