Интерфейс org.apache.logging.log4j.Logger в Apache Log4j 2.12.1 имеет следующие 2 метода:
void info(String message, Object... params);
void info(String message, Supplier<?>... paramSuppliers);
В моем коде я намеревался вызвать второй метод, а второй аргумент был лямбда-параметромSupplier. Удивительно, но во время выполнения был вызван первый метод, который печатал ссылку на объект лямбды вместо фактического значения параметра.
Я озадачен, почему эти методы не помечены компилятором как неоднозначные. Это на Java 11. Я также вижу много других методов в том же интерфейсе Logger, где разница в сигнатуре метода заключается только в том, что один метод принимает Object, а другой метод принимает Supplier<?> в той же позиции в списке аргументов, с типы и порядок соответствия всех других аргументов метода.
Я нашел следующие два вопроса: устранение неоднозначности перегруженных методов, но эти ответы, похоже, не объясняют этого.




По вашему описанию могу предположить, что проблема в неправильном названии пакета для Supplier интерфейса, как правило мы используем java.util.function.Supplier, но org.apache.logging.log4j.Logger интерфейс ожидает Supplier интерфейс от org.apache.logging.log4j.util.Supplier пакета, второй метод будет вызван после изменения имени пакета.
Если все так, как я сказал выше, вопрос неоднозначности прост, сигнатуры не совпадают для второго метода и метод void info(String message, Object... params); будет вызываться по умолчанию для несовпадающих типов параметров, потому что любой класс в Java был расширен классом Object и любым лямбда-выражение является объектом.
Действительно, было, что пакет был не тот. Поставщик параметров, ссылка на который передавалась в вызов log.info, был java.util.function.Supplier, поэтому он не соответствовал концепции поставщика параметров Log4j, то есть org.apache.logging.log4j.util.Supplier.
Я проверил, что в следующем вызове метода ... log.info("Hello, ", () -> "world!"); второй аргумент интерпретируется как org.apache.logging.log4j.util.Supplier и печатается строка Hello, world!. Однако в моем коде я объявил и инициализировал экземпляр java.util.function.Supplier и передал ссылку на него. Таким образом, он не соответствовал типу arg и рассматривался как экземпляр Object. Спасибо, что помогли мне заметить эту деталь. :-)
Можете ли вы опубликовать свой код? Трудно помочь вам с вашей проблемой, если мы не знаем, что конкретно вы делаете.