Java 3 dots (varargs) parameter behavior when no arguments or null

I tried this and got weird behavior from JAVA, can someone explain this to me?

boolean testNull(String... string) { if(string == null) { return true; } else { System.out.println(string.getClass()); return false; } } boolean callTestNull(String s) { return testNull(s); } 

Then I have a test case:

  @Test public void test_cases() { assertTrue(instance.testNull(null)); // NULL assertFalse(instance.testNull()); // NOT NULL assertFalse(instance.callTestNull(null)); // NOT NULL } 
Question: if I call testNull() directly with a null parameter, I will get true back, but if calling callTestNull() with null , which calls testNull() , it tells me that the parameter is not an empty but an empty array.
+44
java ellipsis variadic-functions
Jul 17 '13 at 14:39
source share
1 answer

The question is that I call testNull () directly with the null parameter, I will go back, but if call callTestNull () with zero, which calls testNull (), it tells me that the parameter is not null, but an empty array.

Yes. If you call it with an argument of type String , the compiler knows that String[] cannot be, so it wraps it in an array of strings. So:

 String x = null; testNull(x); 

equivalent to:

 String x = null; testNull(new String[] { x }); 

At this point, the parameter (falsely named) String will have a non-zero value - instead, it will refer to an array of size 1, whose only element is a null reference.

However, when you use the null literal directly in a method call, which is directly converted to String[] , therefore, no packaging is performed.

From JLS section 15.12.4.2 :

If the called method is a method of the arity m variable, it must have n> 0 formal parameters. The final formal parameter m is necessarily of type T [] for some T, and m is invoked with k โ‰ฅ 0 actual argument expressions.

If m is called using k โ‰  n actual argument expressions or if m is called with k = n the actual argument arguments , and the expression type k'th argument is not an assignment compatible with T [] , then the argument list (e1, ... , en-1, en, ..., ek) is evaluated as if it were written as (e1, ..., en-1, new | T [] | {en, ..., ek}) where | T [] | denotes the erasure (ยง4.6) of T [].

(Emphasize mine.)

The bit that I emphasized is why the wrapper only happens when the compile time type is String and not the null type.

+47
Jul 17 '13 at 14:41
source share
โ€” -



All Articles