不明确的方法调用

Heg*_*kar 0 java java-8

下面的代码块

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 + "]");
    }
}

Run Code Online (Sandbox Code Playgroud)

给出catch块中方法调用的错误说明

错误:对日志的引用不明确 log("main", "Error in main",e); ^ 测试中的方法 log(String,Object,Throwable) 和测试中的方法 log(String,String,Object) 都匹配

我无法理解。我在这里遇到了很多问题,但其中大多数都涉及可变参数或泛型。虽然无法确定上面的代码有什么问题。通过 JSL 无法确定我违反了什么规则。任何帮助理解这一点都会很棒。

我知道一些问题被谈到

  • 重命名方法

  • 参数的显式类型转换

作为解决方案,让编译器明确选择哪种方法。但我很期待了解为什么重载方法在这里不起作用。此外,如果将第二个参数类型转换Object为代码工作正常,但为什么呢?

一些问题确实提到了 Java 8 中改进的类型推断而不是 7,所以为了澄清我在 Java 8 上运行它。

khe*_*ood 6

似乎与泛型没有任何关系。

你有一个方法调用

log("main", "Error in main",e);
Run Code Online (Sandbox Code Playgroud)

并且编译器不知道您是否要调用

log(String, Object, Throwable) 
Run Code Online (Sandbox Code Playgroud)

或者

log(String, String, Object)
Run Code Online (Sandbox Code Playgroud)

因为两者都会匹配,并且没有一个比另一个更具体。

为了清楚起见,您可以投射:

log("main", (Object) "Error in main", e);
Run Code Online (Sandbox Code Playgroud)

如果你想要第一个,或者

log("main", "Error in main", (Object) e);
Run Code Online (Sandbox Code Playgroud)

如果你想要第二个。

或者编写一个log更精确地匹配您打算传递给它的参数的方法。