Kotlin中Dagger 2模块使用泛型参数编译报错问题咨询
Dagger 2 泛型参数支持相关说明
Dagger 2 完全支持带泛型参数的类型注入,以下为对应通配符匹配问题的原因及解决方案:
问题场景
测试模块代码
@Module class Test { @Provides fun t( l: List<String>, l1: List<Number> /* 错误指向该依赖 */ ): String { return "String" + l + l1 } @Provides fun list1(): List<Number>{ throw Error() } @Provides fun list() : List<String> { throw Error() } }
Component 声明
@Component(modules = [Test::class]) interface AppComponent { fun str(): String }
编译错误信息
/AppComponent.java:8: error: [Dagger/MissingBinding] java.util.List<? extends java.lang.Number> cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent {
^
java.util.List<? extends java.lang.Number> is injected at
com.example.android.dagger.di.Test.t(…, l1)
java.lang.String is requested at
com.example.android.dagger.di.AppComponent.str()
错误原因
Kotlin的集合类默认带有协变声明,List<Number>在编译为Java字节码时会自动生成通配符变为List<? extends Number>,而Dagger进行依赖绑定时会严格匹配泛型类型,提供的List<Number>和需要注入的List<? extends Number>会被识别为不同的类型,因此触发缺失绑定的错误。
解决方案
可以通过@JvmSuppressWildcards注解关闭Kotlin的通配符生成,有两种常用写法:
- 直接在注入点的泛型参数上添加注解
@Provides fun t( l: List<String>, l1: List<@JvmSuppressWildcards Number> ): String { return "String" + l + l1 }
- 通过
typealias统一封装类型,避免重复添加注解
typealias NumericList = List<@JvmSuppressWildcards Number> @Module class Test { @Provides fun t( l: List<String>, l1: NumericList ): String { return "String" + l + l1 } @Provides fun list1(): NumericList{ throw Error() } // 其余逻辑不变 }
内容的提问来源于stack exchange,提问作者Roman Nazarevych
相关产品推荐
相关产品推荐

