假设,您有两个类 TestA 和 TestB。假设 TestA 扩展了 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; }}现在我创建下一行代码:var getter1: KFunction1<TestA, Int> = TestA::getIntProp如您所见,我从 TestB 的 TestA 类方法访问: TestA::getIntProp所以结果是带有通用参数的 KFunction1 实例 现在我尝试创建下一行代码var getter2: KFunction1<TestA, Int> = TestB::getIntProp它也可以工作和编译,而我预计会有编译错误 最佳答案 这是 generics variance in Kotlin ,其目的是将类型安全的层次结构强加于具有类层次结构本身中的参数的泛型类。类 KFunction1 具有定义为 <in P1, out R> 、带有 P1 修饰符的 in 和带有 R 修饰符的 out 的通用参数。这意味着将有: P1 上的逆变由 in 修饰符引入。如果 KFunction1<PSuper, R> 是 KFunction1<P, R> 的父类(super class)型,则任何 PSuper 都将是 P 的子类型。但是将添加限制,即 P1 只能作为(传入) KFunction1 成员的参数出现。 R 上的协方差由 out 修饰符引入。如果 KFunction1<P, RSub> 是 KFunction1<P, R> 的子类型,则任何 RSub 都将是 R 的子类型。这里 R 将受到限制:它只能用作 KFunction1 成员的返回值(传递出去)。 因此,您将能够将 KFunction1<PSuper, RSub> 分配给 KFunction1<P, R> 类型的变量。这对于 KFunction1 是有意义的,因为任何接收 PSuper 类型参数的函数也可以接收 P 的实例(但反之则不然),并且任何同时返回 RSub 实例的函数返回 R 的实例(但不是副反之)。您可以简单地编写一个示例来显示此行为: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 Baseclass Derived: Base()val i1: Invariant<Base> = Invariant<Derived>() // errorval i2: Invariant<Derived> = Invariant<Base>() // errorval n1: Contravariant<Base> = Contravariant<Derived>() // errorval n2: Contravariant<Derived> = Contravariant<Base>() // OKval v1: Covariant<Base> = Covariant<Derived>() // OKval v2: Covariant<Derived> = Covariant<Base>() // error关于generics - KFunction1 中的 kotlin 泛型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36155108/
10-11 00:51