JDK-6886431 : Handling of "most specific" varargs method inconsistent with JLS
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u14
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2009-09-29
  • Updated: 2014-02-11
  • Resolved: 2014-02-11
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
$ -> java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

$ -> javac -version
javac 1.6.0_14


ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.28-15-generic #49-Ubuntu SMP Tue Aug 18 19:25:34 UTC 2009 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When invoking a method with the following overloaded signatures, I expect an ambiguity error (assuming the arguments are compatible with both):

int f(Object... args);
int f(int... args);

javac treats the second as more specific than the first.  This behavior is sensible (I prefer it), but is inconsistent with the JLS (15.12.2).

Specifics from the spec:
- Per 15.12.2.2, neither method is applicable by subtyping.
- Per 15.12.2.3, neither method is applicable by method invocation conversion (allowing boxing).
- Per 15.12.2.4, both methods are applicable as variable arity methods.
- Per 15.12.2.5, neither is more specific than the other (int <: Object is not true)

Note that "most specific" is defined in terms of subtyping, not method invocation conversion.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the example program.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A compiler error.
ACTUAL -
Successful compilation.  Running demonstrates that f(int...) is selected.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class VarargsMostSpecific {

  static int f(Object... args) { return 1; }
  static int f(int... args) { return 2; }

  public static void main(String... args) {
    int result = f(1, 2, 3);
    System.out.println("result: " + result);
  }

}


---------- END SOURCE ----------

Comments
This was addressed by the patch for JDK-6199075. This particular scenario was also mentioned in the JDK 7 release notes: http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#jdk7 (see "Changes in Most Specific Varargs Method Selection") (Strictly speaking, this reported issue is not a duplicate of 6199075, but I'm using that terminology since it was intentionally addressed by that patch anyway.)
11-02-2014

EVALUATION This behavior is deliberate. My esteemed predecessor even blogged a similar example recently, in a warning about the dangers of overloading. (http://gbracha.blogspot.com/2009/09/systemic-overload.html, "Exhibit 2") Given f(1,2,3), if you make "most specific" rely on method invocation conversion, so that f(int...) is favored in: static int f(Object... a) { return 0; } static int f(int... a) { return 1; } then you should also favor f(int...) in: static int f(Number... a) { return 0; } static int f(int... a) { return 1; } because f(int...) can undergo m.i.conversion to f(Number...) but f(Number...) cannot undergo m.i.conversion to f(int...). However, my javac says f(1,2,3) is ambiguous for this pair. What's going on? Overall though, we should probably make 15.12.2.5 compare types with either <: (subtyping) or <m (conversions allowed in a method invocation context) depending on whether methods were applicable by subtyping or by method invocation conversion. (Note the "or" - 15.12.2.5 is never presented with a set of methods where some were applicable by subtyping and others were applicable by m.i.conversion.)
02-10-2009

EVALUATION Let's consider the following method declarations: int f(Object... a) { ... } int f(int... a) { ... } and the following call site: f(1,2,3) is the call-site ambiguous? According to the JLS it should, as neither Object <: int nor int <: Object. On the other hand, javac (and Eclipse) implement the most specific algorithm in a slightly different way - that is they use subtyping if the applicable candifdates has been found during 15.12.2.2 (methods applicable by subtyping), while they use method invocation conversion otherwise (for candidates discovered during 15.12.2.3 and 15.12.2.4). I think that this makes the most specific algorithm a little bit more flexible, and I'll be happy to leave things as they are. Reassigning to specification for further evaluation.
29-09-2009