Kotlin重写Java方法时泛型类型不匹配问题求解(AnotherType<*>转<String>)
这个问题我之前对接第三方库时也碰到过,本质是Kotlin的泛型类型安全机制在起作用——咱们先搞清楚为什么会报错,再看怎么解决。
为什么会出现类型不匹配?
Android Studio自动生成的重写方法里,param2的类型是AnotherType<*>?,这个通配符*表示它可以是任意类型参数的AnotherType实例。而你的someValue是明确的AnotherType<String>?,Kotlin不允许直接赋值,因为它无法保证传入的param2的泛型参数恰好是String,这是为了避免后续操作出现类型错误。
解决方法
方法1:安全类型转换(推荐)
如果不确定param2一定是AnotherType<String>,用as?做安全转换,转换失败会返回null,不会触发运行时异常:
override fun initialize(param1: AType?, param2: AnotherType<*>?) { this.someValue = param2 as? AnotherType<String> }
这种方式最稳妥,就算第三方库偶尔传入其他类型的AnotherType,也不会导致崩溃。
方法2:非安全强制转换(仅限确定类型时使用)
如果你通过第三方库的文档、源码或者业务逻辑能百分百确定,传入的param2必然是AnotherType<String>,可以用强制转换,同时消除IDE的警告:
override fun initialize(param1: AType?, param2: AnotherType<*>?) { @Suppress("UNCHECKED_CAST") this.someValue = param2 as AnotherType<String>? }
⚠️ 注意:如果实际传入的不是String类型的AnotherType,运行时会抛出ClassCastException,所以一定要确保类型的确定性再用这个方法。
额外补充:泛型协变的小知识
如果第三方库的AnotherType定义时用了out关键字声明协变(比如interface AnotherType<out T>),那AnotherType<*>就能直接赋值给AnotherType<String>?了——但显然这个第三方库没这么定义,所以咱们只能用上面的转换方法。
内容的提问来源于stack exchange,提问作者u84six

