Variable Arity and Fixed Arity Method Calls
The calls at (1) to (4) in Example 3.15 are all variable arity calls, as an implicit Object array is created in which the values of the actual parameters are stored. The reference value of this array is passed to the method. The printout shows that the type of the parameter is actually an array of Objects ([Ljava.lang.Object;).
The call at (6) differs from the previous calls in that the actual parameter is an array that has the same type (Object[]) as the variable arity parameter, without having to create an implicit array. In such a case, no implicit array is created, and the reference value of the array dateInfo is passed to the method. See also the result from this call at (6) in the output. The call at (6) is a fixed arity call (also called a non-varargs call), where no implicit array is created:
flexiPrint(dateInfo); // (6) Non-varargs call
However, if the actual parameter is cast to the type Object as at (7), a variable arity call is executed:
flexiPrint((Object) dateInfo); // (7) new Object[] {(Object) dateInfo}
The type of the actual argument (Object) is now not the same as that of the variable arity parameter (Object[]), resulting in an array of the type Object[] being created in which the array dateInfo is stored as an element. The printout at (7) shows that only the text representation of the dateInfo array is printed, and not its elements, as it is the sole element of the implicit array.
The call at (8) is a fixed arity call, for the same reason as the call at (6). Now, however, the array dateInfo is explicitly stored as an element in an array of the type Object[] that matches the type of the variable arity parameter:
flexiPrint(new Object[]{dateInfo});// (8) Non-varargs call
The output from (8) is the same as the output from (7), where the array dateInfo was passed as an element in an implicitly created array of type Object[].
The compiler issues a warning for the call at (9):
flexiPrint(args); // (9) Warning!
The actual parameter args is an array of the type String[], which is a subtype of Object[]—the type of the variable arity parameter. The array args can be passed in a fixed arity call as an array of the type String[], or in a variable arity call as an element in an implicitly created array of the type Object[]. Both calls are feasible and valid in this case. Note that the compiler chooses a fixed arity call rather than a variable arity call, but also issues a warning. The result at (9) confirms this course of action. A warning at compile time is not the same as a compile-time error. The former does not prevent the program from being run, whereas the latter does.
At (10), the array args of the type String[] is explicitly passed as an Object in a variable arity call, similar to the call at (7):
flexiPrint((Object) args); // (10) Explicit varargs call
At (11), the array args of type String[] is explicitly passed as an array of the type Object[] in a fixed arity call. This call is equivalent to the call at (9), where the widening reference conversion is implicit, but now without a warning at compile time. The two calls print the same information, as is evident from the output at (9) and (11):
flexiPrint((Object[]) args); // (11) Explicit non-varargs call