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

时间:2016-05-02 20:19:52

标签: generics constructor kotlin

不理解Kotlin与Generics的结合。

我试图将我的一些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?

1 个答案:

答案 0 :(得分:4)

问题是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>
)