歧义方法调用

问题描述 投票:0回答:4

下面的代码块

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上运行它。

java java-8
4个回答
4
投票

似乎与泛型无关。

您有一个方法调用

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方法,使其更精确地匹配您要传递给它的参数。


1
投票

由于第三参数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);

0
投票

错误消息指出,有两种方法可以解决您的请求log(String,Object,Throwable)log(String,String,Object)。解释器可以将String强制转换为Object并保持ExceptionThrowable,也可以将Throwable强制转换为Object并保持String不变。两种可能性都需要进行一次强制转换,因此它会引发异常,而不是猜测您希望使用哪种变体。


0
投票

您有两个日志方法,它们都将与调用log("main", "Error in main",e);相匹配

因为您传递了以下参数:

  • “ main”->字符串
  • “主要错误”->字符串
  • e->例外

现在应该调用哪个日志方法?

两个方法都将接受这些参数。

日志方法1

static void log(String methodName, Object message, Throwable t)
  • “ main”-> String->匹配String methodName
  • “主错误”-> String也是Object->匹配Object message
  • e-> Exception-> ExceptionThrowable->匹配Throwable t

日志方法2

static void log(String requestId, String method, Object message)
  • “ main”-> String->匹配String requestId
  • “主错误”-> String->匹配String method
  • e-> Exception-> ExceptionObject->匹配Object message
© www.soinside.com 2019 - 2024. All rights reserved.