An array is an object holding a fixed number of variables of one type, its components, reached by an index from 0. Its length is set when it is created and never changes (JLS chapter 10).
Array types and variables
An array type is written as its component type followed by []. The
component type may itself be an array, so int[][] is an array of
int[]. The length is not part of the type.
int[] numbers; // preferred form
int numbers2[]; // allowed, C style: the brackets belong to the variable
int[] a, b[]; // a is int[], b is int[][]: legal but confusing
String[][] grid;
List<String>[] lists; // allowed as a type, but cannot be created with new
Declaring an array variable does not create an array; the variable holds
null or a reference to one. A final array variable cannot be
pointed at another array, but its components can still be changed.
Creating arrays
ArrayCreationExpression:
new PrimitiveType DimExprs [Dims]
new ClassOrInterfaceType DimExprs [Dims]
new PrimitiveType Dims ArrayInitializer
new ClassOrInterfaceType Dims ArrayInitializer
ArrayInitializer:
{ [VariableInitializer {, VariableInitializer}] [,] }
int[] zeros = new int[5]; // {0, 0, 0, 0, 0}
String[] names = new String[3]; // {null, null, null}
int[] primes = {2, 3, 5, 7, 11}; // initialiser in a declaration
int[] more = new int[] {1, 2, 3}; // array creation with an initialiser (Java 1.1)
int[][] matrix = {{1, 0}, {0, 1}}; // nested initialisers
int[][] jagged = new int[3][]; // rows not created yet: each is null
jagged[0] = new int[1];
jagged[1] = new int[4]; // rows may have different lengths
char[][][] cube = new char[2][3][4]; // every level created
int[] empty = {}; // length 0
- Components start with their default value, or with the initialiser’s values, evaluated left to right.
- A bare initialiser
{…}is allowed only in a declaration or as part ofnew T[] {…}. It cannot be assigned later or passed as an argument alone:m({1, 2})is an error. - A trailing comma is allowed:
{1, 2, 3,}. - Dimension expressions are promoted to
intand evaluated left to right; a negative one throwsNegativeArraySizeException. Too large an array throwsOutOfMemoryError. - Only the leading dimensions may be given:
new int[3][]is fine,new int[][3]is not. - The component type of an array created with
newmust be reifiable, sonew List<String>[3]is an error andnew List<?>[3]is allowed (see Generics).
Access
A component is reached with array[index]. The index expression is
promoted to int, so it may be a byte, short,
char or int, but not a long. Arrays are
therefore limited to 231−1 components.
| Problem | Exception |
|---|---|
The array reference is null | NullPointerException |
| The index is negative or not less than the length | ArrayIndexOutOfBoundsException |
| Storing a value of the wrong run-time type into an array of references | ArrayStoreException |
In a[i] = f(), the array reference and the index are evaluated first,
then f(), and only then are the null and bounds checks made.
Members
| Member | Meaning |
|---|---|
public final int length | The number of components; a field, not a method |
public T[] clone() | A new array with the same components. The copy is shallow: in a multi-dimensional array the sub-arrays are shared. Returns T[], not Object, and throws no checked exception |
Everything else from Object | Including equals, which compares identity; use Arrays.equals or Arrays.deepEquals to compare contents |
Every array type implements Cloneable and
java.io.Serializable. Its superclass is Object.
Covariance and ArrayStoreException
Arrays of references are covariant: if S is a subtype of
T, S[] is a subtype of T[] (JLS 4.10.3). Each
array remembers its component type, and every store is checked at run time
(JLS 10.5):
Object[] objects = new String[2]; // allowed: String[] is a subtype of Object[]
objects[0] = "fine";
objects[1] = 42; // compiles, throws ArrayStoreException
Arrays of primitives are not covariant: int[] is not a
long[] or an Object[], though it is an Object.
Generic collections are invariant instead, which is checked at compile time.
Class objects for arrays
Each array type has a Class object, shared by all arrays of that type
whatever their length: int[].class,
new int[5].getClass() == new int[9].getClass(). Its binary name uses the
JVM’s descriptor form:
| Type | getName() |
|---|---|
int[] | [I |
double[][] | [[D |
String[] | [Ljava.lang.String; |
boolean[], byte[], char[], short[], long[], float[] | [Z, [B, [C, [S, [J, [F |
A char array is not a String
A char[] and a String are unrelated types (JLS 10.9).
String is immutable; a char[] can be changed. Convert with
new String(chars) and text.toCharArray(). String
concatenation with a char[] calls its toString(), giving
something like [C@1b6d3586, not the characters.