Неоднозначный перегруженный метод Apache Log4j

Интерфейс 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<?> в той же позиции в списке аргументов, с типы и порядок соответствия всех других аргументов метода.

Я нашел следующие два вопроса: устранение неоднозначности перегруженных методов, но эти ответы, похоже, не объясняют этого.

  1. Неоднозначный вызов метода при перегрузке метода дженериками и лямбда-выражениями
  2. (Java 8) java.util.function.Supplier

Можете ли вы опубликовать свой код? Трудно помочь вам с вашей проблемой, если мы не знаем, что конкретно вы делаете.

hfontanez 08.01.2021 16:52
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
1
297
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По вашему описанию могу предположить, что проблема в неправильном названии пакета для 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.

Ajoy Bhatia 10.01.2021 07:53

Я проверил, что в следующем вызове метода ... log.info("Hello, ", () -> "world!"); второй аргумент интерпретируется как org.apache.logging.log4j.util.Supplier и печатается строка Hello, world!. Однако в моем коде я объявил и инициализировал экземпляр java.util.function.Supplier и передал ссылку на него. Таким образом, он не соответствовал типу arg и рассматривался как экземпляр Object. Спасибо, что помогли мне заметить эту деталь. :-)

Ajoy Bhatia 10.01.2021 08:09

Другие вопросы по теме