Generics Kotlin和泛型构造函数让我感到困惑

Generics Kotlin和泛型构造函数让我感到困惑,generics,constructor,kotlin,Generics,Constructor,Kotlin,不理解Kotlin与泛型的结合 我正试图将我的一些java迁移到kotlin。其中有两个类是spring数据存储库 以及将存储库类型作为通用参数的通用服务,例如: @Transactional interface ForumRepository : CrudRepository<Forum, Long> { fun findByName(name: String): Forum? } @Transactional 存储库接口:crudepository{ fun findB

不理解Kotlin与泛型的结合

我正试图将我的一些java迁移到kotlin。其中有两个类是spring数据存储库 以及将存储库类型作为通用参数的通用服务,例如:

@Transactional
interface ForumRepository : CrudRepository<Forum, Long> {
    fun findByName(name: String): Forum?
}
@Transactional
存储库接口:crudepository{
fun findByName(名称:String):论坛?
}
然后,GenericKotlin服务:

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)
    }
}
抽象类GenericKotlinService(val存储库:crudepository){
fun findOne(id:Serializable):T{
将repository.findOne(id)返回为T
}
乐趣删除(id:Any){
repository.delete(id)
}
}
但是,现在当我尝试创建一个使用此通用服务和特定Crudepository的服务时 我总是犯错误,例如

class ForumService @Autowired constructor(repository: ForumRepository) : GenericKotlinService<Forum>(repository) {
    open fun findByName(name: String) = repository.findByName(name)
}
class-ForumService@Autowired构造函数(存储库:ForumRepository):GenericKotlinService(存储库){
打开fun findByName(名称:String)=repository.findByName(名称)
}

class-ForumService:GenericKotlinService{
@自动连线
构造函数(存储库:ForumRepository):超级(存储库)
打开fun findByName(名称:String)=repository.findByName(名称)
}
错误是

required CrudRepository<Forum, Long> but got a ForumRepository. 
需要crudepository,但获得了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);
    }
}
公共抽象类GenericService{
私人最终积存库;
公共泛型服务(CRUDepository存储库){
this.repository=存储库;
}
公共T findOne(可序列化id){
return(T)repository.findOne(id);
}
公共作废删除(可序列化id){
删除(id);
}
}
并在ForumService中使用此选项:

class ForumService @Autowired constructor(val repository: ForumRepository) : GenericService<Forum>(repository) {
    open fun findByName(name: String) = repository.findByName(name)
}
class-ForumService@Autowired构造函数(val存储库:ForumRepository):GenericService(存储库){
打开fun findByName(名称:String)=repository.findByName(名称)
}

一切正常。我不知道如何使用我的GenericKotlin服务?

问题是
ForumRepository
不是
crudepository
。但是,如果两个类型参数都处于
out
位置,则可以将其转换为
crudepository
。因此,您可以按照以下方式定义
crudepository

interface CrudRepository<out T, out U>

基本上,这就像Java中的通配符,因为Crudepository是spring数据的一部分,我不能轻易更改它。但是,当我使用您的GenericKotlinService版本并使用一些存储库调用时,例如repository.findOne(id),我会得到一个错误:Kotlin:Out受保护类型“Crudepository”禁止使用公共抽象fun findOne(po:id!),因此我可能需要进一步研究Out关键字。
interface CrudRepository<out T, out U>
abstract class GenericKotlinService<T>(
    val repository: CrudRepository<out Any, out Serializable>
)