Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: overloaded method resolution and varargs -- confusing example

Just when I thought I understood JLS15.12 as it applied to varargs, here's this example:

package com.example.test.reflect;

public class MethodResolutionTest2 {
    public int compute(Object obj1, Object obj2) {
        return 42;
    }   
    public int compute(String s, Object... objects)
    {
        return 43;
    }

    public static void main(String[] args) {
        MethodResolutionTest2 mrt2 = new MethodResolutionTest2();
        System.out.println(mrt2.compute("hi",  mrt2));  
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2}));    
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2, mrt2, mrt2}));
    }
}

which prints out

42
43
43

I understand the first line: JLS15.12 says method resolution happens in phases, and phases 1 and 2 ignore varargs methods to find out if there's a compatible method, with phase 3 (include varargs) happening only if phases 1 and 2 fail. (See the JLS and this SO question.) So compute(String s, Object... objects) always gets ignored if compute(Object obj1, Object obj2) applies.

But I don't understand why 43 is printed for the other two lines. An Object[] is also an instance of an Object, so why does it match the varargs method?


edit:

...and this

Object arg2 = new Object[]{mrt2};
System.out.println(mrt2.compute("hi", arg2));   

prints 42.

like image 215
Jason S Avatar asked May 17 '11 15:05

Jason S


2 Answers

In section 8.4.1:

If the last formal parameter is a variable arity parameter of type T, it is considered to define a formal parameter of type T[].

Since you're explicitly providing an array, this allows the second two calls to match the variable arity method in the first phase, without consideration of variable arity.

like image 188
Andy Thomas Avatar answered Nov 15 '22 16:11

Andy Thomas


Vararg methods can be called with multiple parameters (a, b, c) or as an array ({a, b, c}). Because you are passing an array that matches the type of the varargs it takes precedence.

Reference: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1

like image 30
JustinKSU Avatar answered Nov 15 '22 14:11

JustinKSU