Kotlin List 与 java.util.List 代码中的 java.util.List 泛型类型

Kotlin List vs java.util.List generic type inside Java code

我在将我的项目迁移到 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())

一切都很好,但在 dagger 生成的 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.Listkotlin.collections.List 不兼容, 但是匕首模块 class 用 kotlin 编写并且 returns 有效的 kotlin kotlin.collections.List

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

}

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

好的,我找到了快速解决方案:使用 MutableList<T> 解决了这个问题,并且由于未知原因它与 java.util.List<T> 接缝兼容。

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

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

例如

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

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