如何使用apache commons BooleanUtils.and方法?

How to use apache commons BooleanUtils.and method?

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,使用细节有所不同。

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

这是因为重载可变参数方法不适用于基本类型及其对象包装器类型。 apache-commons-lang3.

无可厚非

可变参数如何工作?

在编译期间,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 类型,并且它与该类型的两种方法都匹配。所以编译器发现没有一个比另一个更合适。它无法决定调用哪个方法most-specific。

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

这就是编译器在 3 个阶段中识别适用方法的方式。查看有关 Choosing the Most Specific Method

的详细信息

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.