javaapache-commons-lang3

How to use apache commons BooleanUtils.and method?


Apache commons-lang has two overloaded BooleanUtils.and methods.

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

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

When calling BooleanUtils.and method, ambiguous method call error is thrown.

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

It can be called using following syntax.

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

But, as per the method's javadoc, the usage detail is different.

JavaDoc

literal boolean

Wrapper Boolean

Valid way to call BooleanUtils.and


Solution

  • This is because overloading a varargs method doesn't work for the primitive type and its object wrapper type. Its nothing to blame about the apache-commons-lang3.

    How varags do work ?

    During the compile time varags method signatures are replaces as Array. Here the BooleanUtils.and methods will convert as

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

    And the parameters you pass to them get replaced to an Array. In this case you will get this

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

    Why Ambigious Method call ?

    You can find that the your converted method parameter is an Array type and it matches the both methods against this type. So compiler finds neither one is more appropriate than the other one by itself. It can't decide which method is the most-specific to call.

    But when you yourself declare BooleanUtils.and(new Boolean[]{Boolean.TRUE, Boolean.TRUE}) or BooleanUtils.and(new boolean[]{true, true}) that exposes your intention to compiler and method is chosen without boxing or autoboxing.

    And this is how compiler identify applicable methods n 3 phases. See details about 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.