在Java 7中使用方法重载时,为什么autoboxing不会覆盖varargs?

Mic*_*ael 19 java compiler-construction autoboxing overloading variadic-functions

我们的Java项目中有一个类LogManager,如下所示:

public class LogManager {

    public void log(Level logLevel, Object... args) {
        // do something
    }

    public void log(Level logLevel, int value, Object... args) {
        // do something else
    }
}
Run Code Online (Sandbox Code Playgroud)

在Debian下用OpenJDK 6编译项目时,每个工作都很好.使用OpenJDK 7时,构建(使用ant完成)会产生以下错误,并且构建失败:

[javac] /…/LogManager.java:123: error: reference to log is ambiguous,
                      both method log(Level,Object...) in LogManager
                      and method log(Level,int,Object...) in LogManager match
[javac]       log(logLevel, 1, logMessage);
[javac]       ^
[javac] /…/SomeOtherClass.java:123: error: reference to log is ambiguous,
                      both method log(Level,Object...) in LogManager
                      and method log(Level,int,Object...) in LogManager match
[javac]       logger.log(logLevel, 1, logMessage);
[javac]             ^
Run Code Online (Sandbox Code Playgroud)

只要1不是自动装箱,方法调用应该是明确的,因为1是一个int并且不能向上转换为Object.那么为什么autoboxing不会在这里推翻varargs?

Eclipse(使用eclipse.org中的tar.gz安装)无论是否安装了OpenJDK 6,都会编译它.

非常感谢你的帮助!

编辑:

编译器获取选项source="1.6"target="1.6"在两种情况下.Eclipse编译注释仅用作注释.

axt*_*avt 17

我猜这与bug #6886431有关,似乎也在OpenJDK 7中修复了.

问题在于JLS 15.12.2.5选择最具体的方法 表明,当前者的形式参数的类型是后者的形式参数的子类型时,一种方法比另一种方法更具体.

由于int不是子类型Object,因此您的方法都不是最具体的,因此您的调用是不明确的.

但是,以下解决方法是可行的,因为它Integer是以下子类型Object:

public void log(Level logLevel, Object... args) { ... }
public void log(Level logLevel, Integer value, Object... args) { ... } 
Run Code Online (Sandbox Code Playgroud)