samedi 6 avril 2019

Kotlin strange behaviour when calling extension function on java.lang.reflect.Proxy object

Today I played with some java.lang.reflect.Proxy in Kotlin, and I was surprised by this behaviour:

import java.lang.reflect.Proxy

interface Dog {
  fun bark()
  fun bark3Times()
}

class DogImpl : Dog {
  override fun bark() = println("Bark!")
  override fun bark3Times() = (0 until 3).forEach { bark() }
}

fun Dog.bark5Times() = (0 until 5).forEach { bark() }

fun main(args: Array<String>) {

  val classLoader = Dog::class.java.classLoader

  val realDog: Dog = DogImpl()

  val proxyDog: Dog = Proxy.newProxyInstance(
    classLoader,
    arrayOf(Dog::class.java)
  ) { _, method, _ ->

    println("Proxy invoked! Method = ${method.name}")
    method.invoke(realDog)

  } as Dog

  println("--- Dog barking 3 times ---")
  proxyDog.bark3Times()

  println()
  println("--- Dog barking 5 times ---")
  proxyDog.bark5Times()

}

Output:

--- Dog barking 3 times ---
Proxy invoked! Method = bark3Times
Bark!
Bark!
Bark!

--- Dog barking 5 times ---
Proxy invoked! Method = bark
Bark!
Proxy invoked! Method = bark
Bark!
Proxy invoked! Method = bark
Bark!
Proxy invoked! Method = bark
Bark!
Proxy invoked! Method = bark
Bark!


The question:

Why in first example proxy is called only for bark3Times calls and not for separate bark calls, but in second example it's not called for bark5Times, but this time is called for every bark call?





Aucun commentaire:

Enregistrer un commentaire