我有一个存储库,它返回实现两个接口的对象
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是一个不扩展A&amp; A的界面。 B,但我想要注入的所有具体实现都实现了所有三个接口
class MyConcreteClass implements A, B, C
所以Spring正确找到了public interface ConcreteRepo extends MyRepository<MyConcreteClass>
,并按照List
类X
中的预期进行了注释。
如果我现在使用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 :(得分:1)
我不确定第一个问题的答案,但第二个问题与您的复杂类型层次结构无关。每当你有List<? extends Something>
时,你将无法向它添加内容,因为这基本上将列表声明为“某种未知类型”的列表,而Java无法确保MyConcreteClass
是一个实例“某种未知类型”。您可以将someTestList
声明为List<MyConcreteClass>
。
答案 1 :(得分:0)
在更多关于泛型的阅读之后,这就是解决方案。首先,正如Philipp Wendler所指出的,someTestList
必须在没有通配符的情况下输入,才能真正输入内容。
List<C> someTestList = new ArrayList<>();
someTestList.add(new MyConcreteClass()); //
此外,在调用Mockito时,编译器需要提示返回类型:
Mockito.<List<? extends C>>when(myRepo.findAll()).thenReturn(someTestList);