Kotlin generics en KFunction1

Supongamos que tiene dos classs TestA y TestB. Supongamos que TestA extiende TestB:

public class TestB { private int intProp; public int getIntProp() { return intProp; } public void setIntProp(int intProp) { this.intProp = intProp; } } public class TestA extends TestB { private String strProp; public String getStrProp() { return strProp; } public void setStrProp(String strProp) { this.strProp = strProp; } } 

Ahora creo la siguiente línea de código:

 var getter1: KFunction1<TestA, Int> = TestA::getIntProp 

Como puede ver, accedí desde el método TestA class de TestB: TestA :: getIntProp SO el resultado es instancia de KFunction1 con parameters generics <TestA, Int>

Ahora trato de crear la siguiente línea de código

 var getter2: KFunction1<TestA, Int> = TestB::getIntProp 

Y también funciona y comstack, mientras espero que haya un error de compilation

Esta es la varianza de generics en Kotlin , su propósito es imponer jerarquía de tipo seguro en classs genéricas con parameters que están en la jerarquía de classs.

La class KFunction1 tiene parameters generics definidos como <in P1, out R> , P1 con modificador in y R out modificador. Esto significa que habrá:

  • Contravarianza en P1 introducida por el modificador in .

    Cualquier KFunction1<PSuper, R> será un subtipo de KFunction1<P, R> si PSuper es un supertipo de P Pero se agregará la limitación de que P1 solo puede aparecer como argumento de (pasado a) los miembros de KFunction1 .

  • Covarianza en R introducida por out modificador de out .

    Cualquier KFunction1<P, RSub> será un subtipo de KFunction1<P, R> si RSub es un subtipo de R Y aquí R será limitado: solo se puede usar como valor de retorno ( KFunction1 ) de los miembros de KFunction1 .

Por lo tanto, podrá asignar KFunction1<PSuper, RSub> a una variable de tipo KFunction1<P, R> .

Esto tiene sentido para KFunction1 , porque cualquier function que recibe un argumento de tipo PSuper también puede recibir una instancia de P (pero no al revés), y cualquier function que devuelva instancias de RSub al mismo time devuelve instancias de R (pero no viceversa) versa).


Simplemente puede componer un ejemplo que muestre este comportamiento:

 class Invariant<T> { fun f(i: Int): T { throw Exception() } // OK fun f(t: T): Int { throw Exception() } // OK } class Contravariant<in T> { fun f(i: Int): T { throw Exception() } // error, T cannot be returned fun f(t: T): Int { throw Exception() } // OK, T is parameter type } class Covariant<out T> { fun f(i: Int): T { throw Exception() } // OK, T is returned fun f(t: T): Int { throw Exception() } // error, T cannnot be parameter type } open class Base class Derived: Base() val i1: Invariant<Base> = Invariant<Derived>() // error val i2: Invariant<Derived> = Invariant<Base>() // error val n1: Contravariant<Base> = Contravariant<Derived>() // error val n2: Contravariant<Derived> = Contravariant<Base>() // OK val v1: Covariant<Base> = Covariant<Derived>() // OK val v2: Covariant<Derived> = Covariant<Base>() // error 
  • Kotlin: ¿Cómo replace el fragment ya abierto con un nuevo fragment en el estudio de Android?
  • Kotlin - Defina la variable globalmente para WebView
  • Prueba unitaria de la function de extensión de Kotlin en las classs de Android SDK
  • Crear una class POJO para Kotlin
  • IntelliJ: error de Kotlin causa parpadeo del mouse y errores en el código
  • ¿Hay una manera simple de get un object por _id en Kotlin?
  • Métodos de ciclo de vida en lenguajes tipados estáticamente
  • Referencia no resuelta DaggerApplicationComponent
  • Mantenga BaseActivity en Java compatible con la actividad de Kotlin
  • Error: ejecución fallida para la tarea ': aplicación: limpiar'. No se puede borrar el file
  • ¿Android Studio 3.0 agrega información de request de parameters?