我正在努力将一个项目从 Java 7 迁移到 Java 8,并且在 Mockito 的“when”情况下遇到编译错误,我很难追踪:
when(queryRunner.query(any(String.class), any(ResultSetHandler.class), anyVararg())).thenReturn(mockedWordResultList);
给我一个编译错误:
java: reference to query is ambiguous both method
<T>query(java.lang.String,java.lang.Object,org.apache.commons.dbutils.ResultSetHandler<T>)
in org.apache.commons.dbutils.QueryRunner and method
<T>query(java.lang.String,org.apache.commons.dbutils.ResultSetHandler<T>,java.lang.Object...)
in org.apache.commons.dbutils.QueryRunner match
此错误发生在 build 1.8.0-b128 中,但不会发生在 1.7.0_45 中。我正在使用 mockito 1.9.5。
在 Java 8 中使用 anyVarArg()
参数匹配的正确方法是什么?
最佳答案
问题是类型推断得到了改进。 anyVararg()
是一种通用方法,但您在嵌套方法调用中使用它。在 Java 8 之前,类型推断的限制强制处理方法 <T> T anyVararg()
喜欢<Object> Object anyVararg()
当作为另一个方法调用的参数而不插入显式类型参数时。
所以只有query(String, ResultSetHandler, Object...)
匹配为第三个参数被视为类型 Object
.
但现在 Java 8 类型推断适用于嵌套方法调用。自<T> T anyVararg()
类型参数 <T>
可以是任何,也可以是ResultSetHandler
以及。所以query(String,Object,ResultSetHandler)
现在也是比赛候选人。
(我在这两种情况下都从外部调用中省略了类型参数 <T>
以减少混淆)
由于我们现在有两个可能的匹配项,因此此处适用正常的方法选择过程。是的,这是模棱两可的。第一个参数相同,String
, 但对于另外两个 ResultSetHandler
比 Object
更具体但是当一个候选人接受第二个参数的更具体类型时,另一个接受第三个参数(和后续参数)。
很明显,允许方法的返回类型为任何类型的类型参数是歧义的来源,但像 Mockito 这样包含此类方法的 API 是 Java 编程的一个极端情况。您将不得不以通用方式强制类型 Matchers.<Desired>anyVararg()
或通过类型转换 (Desired)anyVararg()
.
关于java - mockito:如何在 java 8 中匹配可变参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22620664/