下面的代码块
package com.example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Test {
private static final Logger LOGGER = LogManager.getLogger(Test.class);
public static void main(String[] args) {
try {
log("1234", "main", "try");
} catch (Exception e) {
log("main", "Error in main",e);
}
}
static void log(String methodName, Object message, Throwable t) {
LOGGER.error("[Method Name :" + methodName + "] [Message :" + message + "]", t);
}
static void log(String requestId, String method, Object message) {
LOGGER.error("[RequestId :" + requestId + "]" + "[Method Name :" + method + "] [Message :" + message + "]");
}
}
catch
块中的方法调用给出了错误
错误:对日志的引用不明确log(“ main”,“ main中的错误”,e);^测试中的方法log(String,Object,Throwable)和测试中的方法log(String,String,Object)都匹配
我听不懂。我在这里经历了很多问题,但是其中大多数都涉及varargs或泛型。虽然无法确定上述代码出了什么问题。通过JSL无法确定我违反了什么规则。任何了解这一点的帮助都将非常有用。
我知道有人在谈论问题
重命名方法
参数的显式类型转换
作为解决方案,以使编译器清楚地了解采用哪种方法。但是我期待了解为什么重载方法在这里不起作用。另外,如果将第二个参数类型转换为Object
,则代码可以正常工作,但是为什么呢?
有些问题确实是指Java 8中的类型推断比7有所改进,因此请澄清一下我是在Java 8上运行它。
似乎与泛型无关。
您有一个方法调用
log("main", "Error in main",e);
并且编译器不知道您是否要调用
log(String, Object, Throwable)
或
log(String, String, Object)
因为两者都会匹配,而且两者都不比另一个更具体。
为了清楚起见,您可以投射:
log("main", (Object) "Error in main", e);
如果您想要第一个,或
log("main", "Error in main", (Object) e);
如果要第二个。
或编写一个log
方法,使其更精确地匹配您要传递给它的参数。
由于第三参数Exception
既是Throwable
又是Object
,因此产生了歧义。使用此版本作为第二种日志记录方法:
static void log(String requestId, String method, String message) {
LOGGER.error("[RequestId :" + requestId + "]" + "[Method Name :" + method + "] [Message :" + message + "]");
}
现在以下两个调用不明确:
log("1234", "main", "try");
log("main", "Error in main", e);
错误消息指出,有两种方法可以解决您的请求log(String,Object,Throwable)
和log(String,String,Object)
。解释器可以将String
强制转换为Object
并保持Exception
为Throwable
,也可以将Throwable
强制转换为Object
并保持String
不变。两种可能性都需要进行一次强制转换,因此它会引发异常,而不是猜测您希望使用哪种变体。
您有两个日志方法,它们都将与调用log("main", "Error in main",e);
相匹配
因为您传递了以下参数:
现在应该调用哪个日志方法?
两个方法都将接受这些参数。
static void log(String methodName, Object message, Throwable t)
String
->匹配String methodName
String
也是Object
->匹配Object message
Exception
-> Exception
是Throwable
->匹配Throwable t
static void log(String requestId, String method, Object message)
String
->匹配String requestId
String
->匹配String method
Exception
-> Exception
是Object
->匹配Object message