Method resolution

6

in the example below

public static void foo(Integer i) {
    System.out.println("foo(Integer)");
}

public static void foo(short i) {
    System.out.println("foo(short)");
}

public static void foo(long i) {
    System.out.println("foo(long)");
}

public static void foo(int... i) {
    System.out.println("foo(int ...)");
}

public static void main(String[] args) {
    foo(10);
}

foo calls the long signed method, because the JVM resolves that the closest type of int is long, which is understandable.

It prefers to do this by invoking the Integer or int (Integer) signature method, which would be perfectly compatible.

What is the reason, in terms of language design, for "long" to be more appropriate than Integer or int ...? Is it expensive for the JVM to do this type of casting internally? (either for int [] or Integer)

    
asked by anonymous 20.08.2014 / 13:19

1 answer

6

According to the Java specification , the conversion rules are applied so as not to break compatibility with old versions - which did not support autoboxing or methods with variable number of parameters. In this way, it is considered:

  • One of method conversions , provided they do not involve autoboxing / autounboxing or a variable number of arguments;
  • Idem, but now also allowing autoboxing / autounboxing ;
  • Same, but now also allowing methods with variable number of parameters.
  • In this way, since an applicable method was found during phase 1 (the one with parameter long ), the resolution does not go to phases 2 and 3, so the other options are not considered. Also by the above rules, if there was no solution in phase 1 the next method to be considered would be what receives Integer , and finally what receives int... . What gets short is not valid because it implies a narrowing primitive type ( narrowing primitive conversions ) - which is not applicable to the method call.

        
    20.08.2014 / 13:58