Kotlin类型不匹配:要求Array<Int?>?却找到Array<Int>问题求解
问题原因解析
你遇到的类型不匹配问题本质是混淆了Kotlin中泛型类型的两层可空定义,以及Array的型变特性:
1. 两层可空的区别
你定义的Foo参数fooArg类型为Array<Int?>?,包含两层可空规则:
- 外层
?:整个数组对象本身可以为null,这也是你原本关注的可空规则 - 内层
Int?:数组内存储的每一个元素都可以为null,这是你忽略的约束
而你传入的bar类型是Array<Int>,仅满足「数组本身非空」的要求,但它的元素都是不可空的Int类型,不符合内层元素可空的约束。
2. Array的型变特性
Kotlin中的Array是型变不变的,也就是说Array<Int>和Array<Int?>是完全不兼容的两种类型,不存在父子类关系,哪怕Int是Int?的子类,也不能直接把Array<Int>赋值给Array<Int?>类型的变量。
解决方案
根据你的业务场景可以任选以下一种方案解决:
- 如果你不需要在
Foo内部修改数组元素,仅做读取操作,可以给Foo的参数添加协变修饰符out:
data class Foo( var fooArg: Array<out Int?>? = null, )
此时Array<Int>可以合法传入,符合协变规则。
- 如果你需要保留
Foo的原有参数定义,可以在传参时做类型转换,或者直接声明符合要求的数组类型:
// 方式1:类型转换 val bar: Array<Int> = arrayOf(1,2,3) val foo = Foo(fooArg = bar as Array<Int?>) // 方式2:直接声明元素可空的数组 val bar: Array<Int?> = arrayOf(1,2,3) val foo = Foo(fooArg = bar)
- 如果你的业务场景中
Foo的数组元素本来就不需要支持null,可以直接修改Foo的参数定义:
data class Foo( var fooArg: Array<Int>? = null, )
此时直接传入Array<Int>类型的bar不会有任何问题。
内容的提问来源于stack exchange,提问作者HeyThere
相关产品推荐
相关产品推荐

