Lors du ciblage backend machine virtuelle Java, tous Kotlin les classes sont compilées au bytecode JVM. Le problème avec le bytecode de java est type erasure. Cela signifie que toutes les informations sur les génériques sont supprimées (c'est le problème de Java, pas celui de Kotlin). La déclaration du type fonctionnel (transaction: Transaction) -> Unit
est équivalente à l'utilisation de ce type: Function1<Transaction, Unit>
. Cependant, pour le bytecode JVM, Function1<Transaction, Unit>
et Function1<Transaction, Any>
sont identiques.
Cela signifie que vos deux constructeurs ont la même signature dans le monde JVM.
Vous pouvez "simuler" les constructeurs utilisant companion object
class MyClass {
constructor(db: Database, h: Handler<Transaction>)
companion object {
operator fun invoke(db: Database, handler: (transaction: Transaction) -> Unit) = MyClass(db, Handler<Transaction>({ handler.invoke(it) }))
@JvmName("alternative_constructor")
operator fun invoke(db: Database, handler: (transaction: Transaction) -> Any) = MyClass(db, Handler<Transaction>({ handler.invoke(it) }))
}
}
Et l'utilisation ressemble à ceci:
fun main(args: Array<String>) {
val db = Database()
MyClass(db, Handler { }) //real constructor
MyClass(db){ } //version from companion object
}