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

literal boolean

Wrapper Boolean

Valid way to call BooleanUtils.and

14
TheKojuEffect 13 Мар 2018 в 12:34

2 ответа

Лучший ответ

Это связано с тем, что перегрузка метода varargs не работает для примитивного типа и его типа-оболочки объекта . Нечего винить в apache-commons-lang3.

Как работают вараги?

Во время компиляции сигнатуры метода varargs заменяются на 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}), это раскрывает ваше намерение компилятору и метод выбирается без бокса или автобокса.

И вот как компилятор определяет применимые методы на трех этапах. См. Подробную информацию о Выбор наиболее подходящего Конкретный метод

Первая фаза (§15.12.2.2) выполняет разрешение перегрузки без разрешение упаковки или распаковки конверсий или использование переменной арности вызов метода. Если на этом этапе не найден подходящий метод затем обработка переходит ко второй фазе.

Вторая фаза (§15.12.2.3) выполняет разрешение перегрузки пока разрешает упаковку и распаковку , но по-прежнему исключает использование переменных вызов метода arity. Если во время этого не найдено подходящего метода фаза, затем обработка переходит к третьей фазе.

Третья фаза (§15.12.2.4) позволяет комбинировать перегрузку с методами переменной арности, упаковкой и распаковкой.

3
Shafin Mahmud 13 Мар 2018 в 11:13

Такие ошибки компиляции появились в JDK8. Я считаю, что javadoc Commons-lang был написан в прошлом. (когда JDK7 был последним SDK). Похоже, это побочный эффект одной из функций, выпущенных с JDK8 (вероятно, lambas).

0
Roman Dzhadan 13 Мар 2018 в 09:53