Kotlin和通用构造函数让我感到困惑

不了解Kotlin结合泛型。

我试图把我的一些java移向kotlin。 这些类中的几个是spring-data存储库和一个通用服务,它们将一个类型的存储库作为通用参数,例如:

@Transactional interface ForumRepository : CrudRepository<Forum, Long> { fun findByName(name: String): Forum? } 

那么GenericKotlinService:

 abstract class GenericKotlinService<T>(val repository: CrudRepository<Any, Serializable>) { fun <T> findOne(id: Serializable): T { return repository.findOne(id) as T } fun delete(id: Any) { repository.delete(id) } } 

但是,现在当我尝试创建一个使用这个通用服务与特定的crudRepository的服务时,我总是得到错误,例如

 class ForumService @Autowired constructor(repository: ForumRepository) : GenericKotlinService<Forum>(repository) { open fun findByName(name: String) = repository.findByName(name) } 

要么

 class ForumService : GenericKotlinService<Forum> { @Autowired constructor(repository: ForumRepository) : super(repository) open fun findByName(name: String) = repository.findByName(name) } 

错误是

 required CrudRepository<Forum, Long> but got a ForumRepository. 

当我使用下面的Java GenericService时:

 public abstract class GenericService<T> { private final CrudRepository repository; public GenericService(CrudRepository repository) { this.repository = repository; } public T findOne(Serializable id) { return (T) repository.findOne(id); } public void delete(Serializable id) { repository.delete(id); } } 

并在ForumService中使用这个:

 class ForumService @Autowired constructor(val repository: ForumRepository) : GenericService<Forum>(repository) { open fun findByName(name: String) = repository.findByName(name) } 

一切正常。 我不明白我可以怎样使用我的GenericKotlinService?

问题是ForumRepository不是CrudRepository<Any, Serializable> 。 但是如果两个类型的参数都处于位置CrudRepository<Any, Serializable>它可以转换为CrudRepository<Any, Serializable> 。 所以你可以用下面的方法定义CrudRepository

 interface CrudRepository<out T, out U> 

或者在GenericKotlinService构造函数中接受带有out类型参数的CrudRepository

 abstract class GenericKotlinService<T>( val repository: CrudRepository<out Any, out Serializable> )