Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDK7 Compilation Error: Ambiguity reference

Tags:

java

java-7

I am trying to migrate a legacy code base from java1.6 to 1.7 and I am getting the following error while compiling:

reference to create is ambiguous, both method create(long,Object...) in Meta and method create(Object...) in Meta match

Here Meta is the class name. This error is seen only when compiling with JDK1.7. In 1.6 it is building fine and all the dependencies are working fine as well.

The two polymorphic functions are as follows :

 create(long id, Object... paramters) {
    ....
 }

create(Object... paramters) {
   ....
}

How to resolve this so that the code works for both 1.6 compilation and 1.7 compilation.

EDIT : adding call examples which are throwing an error:

Id.create(1234);
Id.create(id); // id is a long value
like image 318
Vineet Goyal Avatar asked Nov 17 '25 17:11

Vineet Goyal


1 Answers

This is caused by a fix in the Java 7 Compiler:

Incompatibilities between JDK 7 and JDK 6

Area: Tools

Synopsis: Changes in Most Specific Varargs Method Selection

Description: The overload resolution algorithm in the javac compiler has been fixed in how it selects the most specific varargs method when more than one method is applicable to a given call-site (see the JLS, Java SE 7 Edition, section 15.12.2.5).

...

While the javac compiler accepts more code than it did prior to JDK 7, this fix also results in a slight source incompatibility in the following case:

class Test {
    void foo(int... i) {}
    void foo(Object... o) {}

    void test() {
       foo(1,2,3);
    }
}

This code compiles in JDK 6 (the most specific method is foo(int...)). This code does not compile under JDK 7.


To make the code work in both JDKs, you need to give the compiler an additional hint to select the proper method, for example like

Id.create(1234, new Object[0]);
Id.create(id, new Object[0]);

This will call the create(long id, Object... parameters) for both JDK6 and JDK7, and will pass an array of size 0 for the varargs part which is also passed in case of Java 6 with the original code.

Nevertheless, this looks a bit weird, and I would probably choose (for a better readability) to rename one of the methods, so that the method invocation does not rely on the signature.

You should also consider that Java6 is in its end-of-life cycle, so probably another option would be to modify the code so that it is compilable with Java7 in the first place.

like image 76
Andreas Fester Avatar answered Nov 19 '25 06:11

Andreas Fester



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!