Search code examples
javavariadic-functionsautoboxing

Why is foo(1,2,3) not passed to varargs method foo(Object... ) as an Integer[]


Please regard the following lines of code:

public static void main(String[] args)  {
    foo(1,2,3);
    System.out.println("-------------------------------------");
    foo(new Integer(1), new Integer(2), new Integer(3));
    System.out.println("-------------------------------------");
    foo(new Integer[]{1,2,3});
    System.out.println("-------------------------------------");
    foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});
}

public static void foo(Object... bar) {
    System.out.println("bar instanceof Integer[]:\t" + (bar instanceof Integer[]));
    System.out.println("bar[0] instanceof Integer:\t" + (bar[0] instanceof Integer));
    System.out.println("bar.getClass().isArray():\t" + bar.getClass().isArray());
}

The output of this code snippet is:

bar instanceof Integer[]:   false
bar[0] instanceof Integer:  true
bar.getClass().isArray():   true
-------------------------------------
bar instanceof Integer[]:   false
bar[0] instanceof Integer:  true
bar.getClass().isArray():   true
-------------------------------------
bar instanceof Integer[]:   true
bar[0] instanceof Integer:  true
bar.getClass().isArray():   true
-------------------------------------
bar instanceof Integer[]:   true
bar[0] instanceof Integer:  true
bar.getClass().isArray():   true

And this confuses me quite a bit! I don't understand why in case of foo(1,2,3) the term bar instanceof Integer[] is false.

If in these cases bar is not an instance of Integer[] what else is it an instance of?


Solution

    • foo(1,2,3);

    This one autoboxes 1, 2 and 3 to Integer(s) and since they are Object sub-types, an Object[] array is created, consisting of three Integers. An array Object[] is not Integer[] and that's why you get false.


    • foo(new Integer(1), new Integer(2), new Integer(3));

    Here, no auto boxing applies, but in the end you will again have an array Object[] that consist of three Integers. Again, Object[] is not Integer[] and that's why you get false.


    • foo(new Integer[]{1,2,3});

    Here you have only one argument, unlike the previous two cases, where you had three wrapped into one array. So, having only one argument Integer[], at Runtime the comparison bar instanceof Integer[] will return true, because integers is what you actually have.


    • foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});

    Same as the previous one - at Runtime you will check if the provided array Integer[] is an array of Integers, which is true.