views:

69

answers:

5

If I have a vararg Java method foo(Object ...arg) and I call foo(null, null), I have both arg[0] and arg[1] as nulls. But if I call foo(null), arg itself is null. Why is this happening?

+1  A: 

You need an explicit cast to Object:

foo((Object) null);

Otherwise the argument is assumed to be the whole array that the varargs represents.

Bozho
Not really, see my post.
The Elite Gentleman
well, I think you are wrong :)
Bozho
Oops, same here...sorry, midnight oil.
The Elite Gentleman
+1  A: 

This is because a varargs method can be called with an actual array rather than a series of array elements. When you provide it with the ambiguous null by itself, it assumes the null is an Object[]. Casting the null to Object will fix this.

ColinD
+7  A: 

The issue is that when you use the literal null, Java doesn't know what type it is supposed to be. It could be a null Object, or it could be a null Object array. For a single argument it assumes the latter.

You have two choices. Cast the null explicitly to Object or call the method using a strongly typed variable. See the example below:

public class Temp{
   public static void main(String[] args){
      foo("a", "b", "c");
      foo(null, null);
      foo((Object)null);
      Object bar = null;
      foo(bar);
   }

   private static void foo(Object...args) {
      System.out.println("foo called, args: " + asList(args));
   }
}

Output:

foo called, args: [a, b, c]
foo called, args: [null, null]
foo called, args: [null]
foo called, args: [null]
Mike Deck
A: 

Well, my gut says it is because your passing a null object reference, rather than a reference to a null. Hard for me to explain but at the same time I'm not so suprised. Maybe cast it? If your method is expecting at least one argument maybe do public void foo(Object first, Object... rest) instead?

raeb
+1  A: 

You need to understand what varargs does. The varargs method takes an arbitrary number of values and puts the value into an array before the method is invoked.

if you do foo(null); it is translated as foo(Object[] arg) since 1 value is passed. Since its only 1 parameter value passed, it's loosely interpreted as Object[] args = null and that's why args is null in your case.

foo(null, null) potentially creates an Object[] arg where arg[0] = arg[1] = null;

Hope this helps.

The Elite Gentleman
I'm not sure your explanation makes sense. When you do `foo(null)`, the method is still `foo(Object[] arg)`... the `null` is just getting interpreted as the whole `Object[] arg` rather than the single element of `arg`. Varargs cannot change the actual type of the parameter based on the number of arguments to the method.
ColinD
@ColinD, thanks...I didn't realise my mistake there. Reupdated.
The Elite Gentleman