网通社科技快报
Kotlin泛型in out与星号通配符深度解析 掌握协变逆变提升类型安全
Kotlin泛型通过in、out与*(星号通配符)实现类型安全的协变与逆变,显著区别于Java的使用-site variance。基础泛型默认为不变性,如Box<Animal>与Box<Cat>互不兼容;而out修饰的类型参数表示协变,适用于只读场景,例如List<out Animal>可接收Cat列表,因仅允许读取元素,禁止写入以保障安全。in修饰则表示逆变,用于只写场景,如Comparator<in Animal>可安全处理Cat对象,因compare仅接收输入参数,避免返回类型污染。星号通配符*是类型投影简化写法,等价于out Any?或in Nothing,取决于上下文,适用于无需具体类型的场景,但会丢失类型信息,应优先使用明确的in/out声明。Kotlin将变异性声明前置至类型定义层,使API契约更清晰——如标准库中List<T>标注协变、MutableList<T>保持不变、其写入接口隐含逆变逻辑。常见误区包括:在需写入的集合误用out导致编译失败;过度依赖*增加运行时风险;忽略Java互操作时平台类型(T!)带来的隐性隐患。合理运用in/out可减少强制转换与unchecked警告,例如事件监听器接口EventListener<T>中onEvent(event: T)天然支持父类监听子类事件。需注意JVM类型擦除仍存在限制,如运行时无法获取T具体类型、基本类型需装箱等,但Kotlin通过编译期检查与智能推断大幅拦截风险。掌握in/out本质在于理解数据流向:‘向外提供’用out,‘向内接收’用in,使泛型从语法难点转化为高效工具。