不了解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>位置,则可以将其转换为out。因此,您可以通过以下方式定义CrudRepository

interface CrudRepository<out T, out U>

或在CrudRepository构造函数中接受带有out类型参数的GenericKotlinService
abstract class GenericKotlinService<T>(
    val repository: CrudRepository<out Any, out Serializable>
)

08-05 15:02