MST

星途 面试题库

面试题:Kotlin类型参数约束与逆变协变的复杂场景分析

假设有如下Kotlin代码: ```kotlin interface Animal class Dog : Animal class Puppy : Dog interface Handler<in T> { fun handle(t: T) } class DogHandler : Handler<Dog> { override fun handle(dog: Dog) { println("Handling a dog") } } fun process(handler: Handler<in Puppy>) { // 这里要处理Puppy对象,通过handler处理 } ``` 1. 解释 `Handler<in T>` 中 `in` 关键字的作用,以及它是如何影响类型兼容性的。 2. 在 `process` 函数中,传入 `DogHandler` 的实例是否合法?请详细说明原因,结合Kotlin类型参数约束与逆变协变的知识。
30.4万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
  1. in 关键字的作用及对类型兼容性的影响

    • 作用in 关键字用于声明类型参数为逆变(contravariant)。在 Handler<in T> 中,T 是逆变类型参数。这意味着 Handler 接口的使用者只能在其方法参数中使用 T 类型(如 fun handle(t: T)),而不能在返回值或其他输出位置使用 T
    • 对类型兼容性的影响:对于逆变类型参数,类型兼容性与通常的子类型关系相反。如果 AB 的子类型,那么 Handler<B>Handler<A> 的子类型。例如,如果 PuppyDog 的子类型,那么 Handler<Dog>Handler<Puppy> 的子类型。这与协变(out)的情况相反,协变时类型兼容性与子类型关系一致。
  2. 传入 DogHandler 的实例是否合法及原因

    • 合法:因为 Handler<in T> 中的 T 是逆变类型参数。PuppyDog 的子类型,根据逆变规则,Handler<Dog>Handler<Puppy> 的子类型。DogHandler 实现了 Handler<Dog>,所以 DogHandler 的实例可以作为 Handler<Puppy> 类型的参数传入 process 函数。在 process 函数中,Handler<in Puppy> 要求可以处理 Puppy 对象,由于 DogHandler 能处理 Dog 对象,而 PuppyDog 的子类型,所以 DogHandler 也能处理 Puppy 对象,符合函数参数类型要求。