Guice注入指定有序Vehicle实现类列表报错的解决咨询
Guice注入指定有序Vehicle实现类的问题解决
需要向Service注入一组指定顺序的Vehicle接口实现类,因@ProvidesIntoSet会注入所有实现类所以弃用,在Module中编写了如下@Provides方法:
@Provides @Named(value = "vehicles") fun getVehicles( car: Car, bus: Bus, ): List<Vehicle> { return listOf( car, bus ) }
但在VehicleService中注入时:
class VehicleService @Inject constructor( @Named("vehicles") private val vehicles: List<Vehicle>, ... )
出现错误:
No implementation for List<? extends Vehicle> annotated with @Named(value="vehicles") was bound
错误原因
Kotlin的List默认是协变类型(List<out T>),编译后会被Java识别为List<? extends Vehicle>;而你通过@Provides绑定的是具体的List<Vehicle>类型,Guice无法将这两个泛型类型匹配,因此报错。
解决方法
方法1:用@JvmSuppressWildcards抑制协变通配符
通过注解消除Kotlin泛型的协变特性,让Guice识别为具体的List<Vehicle>类型。
方式A:修改@Provides方法的返回类型
@Provides @Named("vehicles") fun getVehicles( car: Car, bus: Bus ): List<@JvmSuppressWildcards Vehicle> { return listOf(car, bus) }
方式B:修改注入点的参数类型
class VehicleService @Inject constructor( @Named("vehicles") private val vehicles: List<@JvmSuppressWildcards Vehicle>, ... )
方法2:显式绑定泛型类型(TypeLiteral)
在Module的configure方法中,使用Guice的TypeLiteral明确绑定List<Vehicle>类型,避免泛型类型不匹配:
override fun configure() { // 定义泛型类型字面量 val vehicleListType = object : TypeLiteral<List<Vehicle>>() {} // 绑定带@Named的List<Vehicle>到自定义Provider bind(vehicleListType) .annotatedWith(Names.named("vehicles")) .toProvider(object : Provider<List<Vehicle>> { @Inject lateinit var car: Car @Inject lateinit var bus: Bus override fun get(): List<Vehicle> { return listOf(car, bus) } }) }
这种方式更直观地指定了绑定的泛型类型,适合复杂场景。
内容的提问来源于stack exchange,提问作者CuriousCoder
相关产品推荐
相关产品推荐

