java - 这个Java方法调用的歧义在哪里?

标签 java mockito powermock variadic-functions ambiguity

我收到一个我不理解的“对 make 的引用不明确”的编译器错误。

我有这两种方法

public static <T> T make(String name, Class<T> parentClass, 
                         boolean rethrowRuntimeExceptions, 
                         Object... params) throws DLException

 public static <T> T make(String name, Class<T> parentClass,
                          Object... params) throws DLException

这行代码被标记为不明确

  String className = "clsNme";
  String one = "1";
  String two = "2";     
  SimpleFactory.make(className, Object.class, false, one, two);

这里是错误

both method <T#1>make(String,Class<T#1>,boolean,Object...) in SimpleFactory and method <T#2>make(String,Class<T#2>,Object...) in SimpleFactory match
    [javac]   where T#1,T#2 are type-variables:
    [javac]     T#1 extends Object declared in method <T#1>make(String,Class<T#1>,boolean,Object...)
    [javac]     T#2 extends Object declared in method <T#2>make(String,Class<T#2>,Object...)

boolean 参数的存在不会使第一种方法比第二种方法更匹配吗?

如果重要的话,这是 PowerMock 测试的一部分这是完整的方法

public void makeCallsMakeWithFalse() throws Throwable {
  Object expected = mock(Object.class);
  String className = "clsNme";

  String one = "1";
  String two = "2";

  spy(SimpleFactory.class);

  doReturn(expected).when(SimpleFactory.class);
  SimpleFactory.make(className, Object.class, false, one, two);  // causes error

  Object observed = SimpleFactory.make(className, Object.class, one, two); // doesn't cause error
  assertEquals(expected, observed);

  verifyStatic();
  SimpleFactory.make(className, Object.class, false, one, two);  // causes error

如果有帮助:我使用的是 javac 1.8.0_77、Mokito 1.10.19 和 Powermock 1.6.3。

最佳答案

编译器首先尝试找到不涉及自动装箱/拆箱或变量元数调用的匹配签名。变量元数调用是指通过将参数列表作为最后一个参数(而不是数组)传递来调用可变参数方法。

在您的情况下,两者都涉及变量 arity 调用。发生这种情况时,将选择最具体的重载。对于您的情况,JLS 中定义的都不是更具体的。这本质上是因为类型 booleanObject 都不是对方的子类型。

稍微简化一下您的示例,以下代码无法编译。

static void foo(boolean b, Object... arr) {

}

static void foo(Object... arr) {

}

public static void main(String[] args) {
    foo(true);
}

第一个版本不接受Object 类型的单个参数,第二个版本不接受boolean 类型的单个参数。因此两者都不是更具体。 (自动装箱只会让它看起来好像您可以将boolean 作为Object 类型的参数传递一样)。

另一方面,如果将 boolean 替换为 Boolean,它会编译,因为 BooleanObject< 的子类型

关于java - 这个Java方法调用的歧义在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36380347/

相关文章:

java - 如何模拟由静态方法设置的最终静态变量?

java - 模拟 RestTemplate API 调用

java - JUnit/Mockito 测试因奇怪的原因失败

java - Powermock mockstatic 不能继承最终类

java - 如何从 Java 与 ADFS 通信?

java - 如何指定statsd客户端端口?

java - 商业网站架构问题

java - PowerMock - 单例实例测试

java - 无法使用 JUnitParams 运行 PowerMock

java - Maven 嵌入器 : Compiler dependency could not be resolved - No connector factories available