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> )