We declare the cards field as an array of type Card by following the type name in the declaration with
square brackets [ and ]. We initialize cards to a new array with DECK_SIZE variables of type Card. Each
Card element in the array is implicitly initialized to null. An array's length is fixed when it is created and
can never change.
The println method invocation shows how array components are accessed. It encloses the index of the
desired element within square brackets following the array name.
You can probably tell from reading the code that array objects have a length field that says how many
elements the array contains. The bounds of an array are integers between 0 and length-1, inclusive. It is a
common programming error, especially when looping through array elements, to try to access elements that
are outside the bounds of the array. To catch this sort of error, all array accesses are bounds checked, to ensure
that the index is in bounds. If you try to use an index that is out of bounds, the runtime system reports this by
throwing an exception in your programan ArrayIndexOutOfBoundsException. You'll learn about
exceptions a bit later in this chapter.
An array with length zero is an empty array. Methods that take arrays as arguments may require that the array
they receive is non-empty and so will need to check the length. However, before you can check the length of
an array you need to ensure that the array reference is not null. If either of these checks fail, the method may
report the problem by throwing an IllegalArgumentException. For example, here is a method that
averages the values in an integer array:
static double average(int[] values) {
if (values == null)
throw new IllegalArgumentException();
else
if (values.length == 0)
throw new IllegalArgumentException();
else {
double sum = 0.0;
for (int i = 0; i < values.length; i++)
sum += values[i];
return sum / values.length;
}
}
This code works but the logic of the method is almost completely lost in the nested ifelse statements
ensuring the array is non-empty. To avoid the need for two if statements, we could try to test whether the
argument is null or whether it has a zero length, by using the boolean inclusive-OR operator (|):
if (values == null | values.length == 0)
throw new IllegalArgumentException();
Unfortunately, this code is not correct. Even if values is null, this code will still attempt to access its
length field because the normal boolean operators always evaluate both operands. This situation is so
common when performing logical operations that special operators are defined to solve it. The conditional
boolean operators evaluate their right-hand operand only if the value of the expression has not already been
determined by the left-hand operand. We can correct the example code by using the conditional-OR (||)
operator: