Alex Rivera | Logout

Why doesn't autoboxing overrule varargs when using method overloading in Java 7?

Asked 2011-10-07T15:25:18.510
19

We have a class LogManager in our Java project which looks like this:

public class LogManager {

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

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

When compiling the project with OpenJDK 6 under Debian everyting works fine. When using OpenJDK 7 the build (done with ant) produces the following errors and the build fails:

[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]             ^

As long as the 1 is not autoboxed, the method call should be unambiguous as 1 is an int and cannot be upcast to Object. So why doesn't autoboxing overrule varargs here?

Eclipse (installed using the tar.gz from eclipse.org) compiles it no matter if OpenJDK 6 is installed or not.

Thank's a lot for your help!

Edit:

The compiler gets the option source="1.6" and target="1.6" in both cases. The Eclipse compiling note is just meant as a comment.

Edit
Report

1 Answer

2

Eclipse uses it's own compiler, so what Eclipse does eventually follows what the SUN / Oracle provided compilers does; however, sometimes (like in this case) there are differences.

This could "go either way" and probably in Java 6, the issue wasn't addressed in detail. Since Java has a strong requirement to reduce the number of "ambiguous" meanings in its environment (to enforce same behavior across many platforms), I'd imagine that they tightened up (or directly specified) the decided behavior in the 7 release.

You just got caught on the "wrong" side of new specification clarification. Sorry, but I think you'll be writing a bit of this

public void log(Level logLevel, Object... args) {
    if (args != null && args[0] instanceof Integer) {
      // do something else
    } else {
      // do something
    }
}

into your new solution.

answered 2011-10-07T15:37:52.703

Your Answer