14

Apache commons-lang有两个重载BooleanUtils.and方法。

public static boolean and(final boolean... array) {

public static Boolean and(final Boolean... array) {

调用BooleanUtils.and方法时,会抛出模棱两可的方法调用错误。

java: reference to and is ambiguous
  both method and(boolean...) in org.apache.commons.lang3.BooleanUtils and method and(java.lang.Boolean...) in org.apache.commons.lang3.BooleanUtils match

可以使用以下语法调用它。

BooleanUtils.and(new Boolean[]{Boolean.TRUE, Boolean.TRUE});

但是,根据方法的 javadoc,使用细节是不同的。

JavaDoc

文字布尔值

包装布尔值

调用 BooleanUtils.and 的有效方法

4

2 回答 2

5

这是因为重载 varargs 方法不适用于原始类型及其对象包装类型。apache-commons-lang3 没什么可责备的。

varags 是如何工作的?

在编译期间 varags 方法签名被替换为Array. 这里的BooleanUtils.and方法将转换为

public static boolean and(final boolean[] array) { ... 
}

public static boolean and(final boolean[] array) { ... 
}

并且您传递给他们的参数将被替换为Array. 在这种情况下,你会得到这个

BooleanUtils.and(new boolean[]{true, true}) 
BooleanUtils.and(new Boolean[]{Boolean.TRUE, Boolean.TRUE})

为什么有歧义方法调用?

您会发现您转换的方法参数是一种Array类型,并且它与这两种方法都匹配这种类型。所以编译器发现没有一个比另一个更合适。它不能决定哪个方法是最具体的调用。

但是,当您自己声明BooleanUtils.and(new Boolean[]{Boolean.TRUE, Boolean.TRUE})BooleanUtils.and(new boolean[]{true, true})将您的意图暴露给编译器和方法时,选择不装箱或自动装箱。

这就是编译器在 3 个阶段中识别适用方法的方式。查看有关选择最具体方法的详细信息

第一阶段(第 15.12.2.2 节)执行重载决议,不允许装箱或拆箱转换,或使用变量 arity 方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。

第二阶段(第 15.12.2.3 节)执行重载决议,同时允许装箱和拆箱,但仍然排除使用变量 arity 方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。

第三阶段(第 15.12.2.4 节)允许将重载与可变参数方法、装箱和拆箱相结合。

于 2018-03-13T10:21:53.663 回答
0

JDK8中出现了这样的编译错误。我相信,commons-lang 的 javadoc 是过去写的。(当 JDK7 是最新的 SDK 时)。似乎,这是随 JDK8 发布的功能之一的副作用(可能lambas)。

于 2018-03-13T09:53:29.447 回答