在将项目迁移到Kotlin时,我陷入了奇怪的行为。
它是在我尝试生成匕首注射器时发生的。 Java或Dagger中的问题,有人无法从通用类型解析Kotlin List
示例:
interface CacheEntity<Result> {
fun onResult(result: Result)
fun getUpdatableData(): Observable<Result>
}
class CacheRepository< Result, Entity:CacheEntity<Result> >(
val entity: Entity) {
// do some operations with Entity
fun doSome() {
entity.getUpdatableData()
entity.onResult(...)
}
}
class UserRepository: CacheEntity<User> {
override fun onResult(result: User) {}
override fun getUpdatableData(): Observable<User> {}
}
现在,如果我要创建缓存的用户存储库实例,一切正常 然后这段代码使用匕首注入法转换为应用程序
val cachedUserRepo = CacheRepository<User, UserRepository>(UserRepository())
但是!如果我要生成数据列表
class OrdersRepository: CacheEntity<List<Order>> {
// overrides CacheEntity methods
}
val cachedOrdersRepo = CacheRepository<List<Order>, OrdersRepository>(OrdersRepository())
一切都很好,但是用匕首生成的Java代码却不行: MyComponent.java
private CacheRepository<List<Order>, OrdersRepository> cachedOrdersRepository;
构建时出错
error: type argument OrdersRepository is not within bounds of type-variable Entity
private Provider<CachedRepository<List<Order>, OrdersRepository>> cachedOrdersRepository;
^
where Entity,Result are type-variables:
Entity extends CacheEntity<Result> declared in class CacheRepository
Result extends Object declared in class CacheRepository
Java代码包含 java.util.List ,它与 kotlin.collections.List 不兼容, 但是用kotlin编写的dagger模块类,并返回有效的kotlin kotlin.collections.List
@Module
object RepoModule {
@JvmStatic
@Provides
fun provideCacheOrdersRepository(): CacheRepository<List<Order>, OrdersRepository> {
return CacheRepository(OrdersRepository())
}
}
那么,如何解决呢?我有几个主意,但我不喜欢这样:
用Java重写dagger模块,在我转换为Kotlin之前它就起作用了
使用 java.util.List 强制执行,但这是一个非常糟糕的主意
答案 0 :(得分:2)
这与Kotlin列表的字节码转换以及签名中添加的通配符有关,从而使其成为java.util.List<? extends T>
而不是java.lang.List<T>
。
要在不切换为不变类型(例如MutableList
)的情况下进行修复,则应在@JvmSuppressWildcards
类型上使用List
:
例如
class OrdersRepository: CacheEntity<List<@JvmSuppressWildcards Order>>
我只添加了完整代码的一部分,您应该检查列表的用法并在其上使用@JvmSuppressWildcards
。
答案 1 :(得分:0)
好吧,我找到了一个快速的解决方案:使用MutableList<T>
解决了此问题,并且由于未知原因它与java.util.List<T>
兼容。