【问题标题】:Apache Log4j Ambiguous Overloaded MethodApache Log4j 模糊重载方法
【发布时间】:2020-12-10 22:28:45
【问题描述】:

Apache Log4j 2.12.1中的接口org.apache.logging.log4j.Logger有以下2个方法:

void info(String message, Object... params);

void info(String message, Supplier<?>... paramSuppliers);

在我的代码中,我的意图是调用第二个方法,第二个 arg 是 lambda paramSupplier。令人惊讶的是,在运行时,第一个方法被调用,它打印了 lambda 的 obj 引用而不是实际的参数值。

我很困惑为什么这些方法没有被编译器标记为模棱两可。这是在 Java 11 上。我还在同一个 Logger 接口中看到了许多其他方法,其中方法签名的区别只是一个方法采用 Object 而另一种方法采用 Supplier&lt;?&gt; 在同一位置在 args 列表中,与所有其他方法 args 的类型和顺序匹配。

我发现了以下两个问题:重载方法消歧,但这些答案似乎无法解释这一点。

  1. Ambiguous method call when overloading method with generics and lambdas
  2. (Java 8) java.util.function.Supplier

【问题讨论】:

  • 你能发布你的代码吗?如果我们不知道您具体在做什么,我们很难帮助您解决问题。

标签: java log4j overloading


【解决方案1】:

根据您的描述,我可以假设问题出在Supplier 接口的包名不正确,因为我们使用的是java.util.function.Supplier,但org.apache.logging.log4j.Logger 接口需要来自org.apache.logging.log4j.util.Supplier 包的Supplier 接口,第二个更改包名后将调用方法。

如果一切如我上面所说,歧义的问题很简单,第二个方法的签名不匹配,void info(String message, Object... params); 方法将作为参数类型不匹配的默认调用,因为 Java 中的任何类都已扩展通过Object 类,任何 lambda 表达式都是一个对象。

【讨论】:

  • 确实是包不一样。被传递给log.info调用的参数供应商是java.util.function.Supplier,这就是为什么它与Log4j的参数供应商概念不匹配,即org.apache.logging.log4j.util.Supplier
  • 我检查过,在下面的方法调用中...log.info("Hello, ", () -&gt; "world!"); 第二个参数被解释为org.apache.logging.log4j.util.Supplier 并且字符串Hello, world! 被打印出来。但是,在我的代码中,我已经声明并初始化了一个 java.util.function.Supplier 实例,并且正在传递对它的引用。因此,它与 arg 类型不匹配,并被视为 Object 实例。感谢您帮助我注意到这个细节。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-20
  • 2014-07-11
  • 2017-11-11
  • 2014-01-11
  • 2013-11-28
  • 1970-01-01
  • 2019-08-11
相关资源
最近更新 更多