首页 > 解决方案 > Java 代码中的 Kotlin List 与 java.util.List 泛型类型

问题描述

在将我的项目迁移到 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 代码包含与kotlin.collections.List不兼容的java.util.List,但是用 kotlin 编写的 dagger 模块类并返回有效的 kotlin kotlin.collections.List

@Module
object RepoModule {
  @JvmStatic
  @Provides
  fun provideCacheOrdersRepository(): CacheRepository<List<Order>, OrdersRepository> {
    return CacheRepository(OrdersRepository())
  }

}

那么,如何解决这个问题呢?我有几个想法,但我不喜欢这样:

标签: javakotlindagger-2

解决方案


这与 Kotlin 列表的字节码转换和签名中添加的通配符有关,使其成为 ajava.util.List<? extends T>而不是java.lang.List<T>.

要在不切换到不变类型(例如MutableList)的情况下修复它,您应该@JvmSuppressWildcardsList类型上使用:

例如

class OrdersRepository: CacheEntity<List<@JvmSuppressWildcards Order>>

我只添加了你完整代码的一个片段,你应该检查你的列表用法并使用@JvmSuppressWildcards它们。


推荐阅读