2017-04-13 52 views
1

我有一个返回一个对象实现两个接口泛型:如何处理多个界类型的类层次结构

public interface MyRepository<T extends A & B> extends JpaRepository<T, Long> 
    List<T> findAll(); 
    ... 

使用Spring我注入的这些都实现到另一个类,但另外指定的存储库的泛型类型本身应该另外实现某个接口C

class X { 
    @Autowired 
    private List<MyRepository<? extends C> myCRepos; 

注意,C是不延长&为B接口,但是所有的具体实现我想要注入实现所有三个接口

class MyConcreteClass implements A, B, C 

所以一个public interface ConcreteRepo extends MyRepository<MyConcreteClass>正确的春天发现和注入,如预期X类的List

如果我现在使用findAll方法,则其返回类型由IDE推断为List<? extends C>

为什么返回类型不是宁可List<? extends A & B & C>

为了测试我想嘲笑这个findAll等返回正确类型的对象,但按照已经失败:

List<? extends C> someTestList = new ArrayList<>(); 
someTestList.add(new MyConcreteClass()); // 
// has error like 
// The method add(capture#1-of ? extends C) in the type 
// List<capture#1-of ? extends C> is not applicable for the arguments (C) 

我应该怎么解决这个问题?

最后,我想嘲笑这件事

Mockito.when(myRepo.findAll()).thenReturn(someTestList); 

同样的问题,应该是什么类型someTestList以及如何创建呢?

+0

并Ç延伸A和B? – Ishnark

+0

C号是A和B的分开 – Philipp

回答

0

在对泛型进行了一些更多的阅读之后,下面是解决方案。首先,正如Philipp Wendler指出的那样,someTestList必须键入没有通配符才能够实际输入内容。

List<C> someTestList = new ArrayList<>(); 
someTestList.add(new MyConcreteClass()); // 

此外,在调用的Mockito,编译器需要返回类型一个提示:

Mockito.<List<? extends C>>when(myRepo.findAll()).thenReturn(someTestList); 
1

我不确定你的第一个问题的答案,但第二个问题与你的复杂类型层次无关。无论何时你有一个List<? extends Something>,你将无法添加一些东西,因为这基本上将该列表声明为“未知类型”的列表,并且Java不能确保MyConcreteClass是“某些未知类型”的实例。您可以通过声明someTestListList<MyConcreteClass>来解决此问题和第三个问题。