Table of Contents
In the Java programming language,arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of typeObject (§4.3.2). All methods of classObject may be invoked on an array.
An array object contains a number of variables. The number of variables may be zero, in which case the array is said to beempty. The variables contained in an array have no names; instead they are referenced by array access expressions that use non-negative integer index values. These variables are called thecomponents of the array. If an array hasn components, we sayn is the length of the array; the components of the array are referenced using integer indices from 0 ton - 1, inclusive.
All the components of an array have the same type, called thecomponent type of the array. If the component type of an array isT, then the type of the array itself is writtenT[].
The component type of an array may itself be an array type. The components of such an array may contain references to subarrays. If, starting from any array type, one considers its component type, and then (if that is also an array type) the component type of that type, and so on, eventually one must reach a component type that is not an array type; this is called theelement type of the original array, and the components at this level of the data structure are called theelements of the original array.
There are some situations in which an element of an array can be an array: if the element type isObject orCloneable orjava.io.Serializable, then some or all of the elements may be arrays, because any array object can be assigned to any variable of these types.
Array types are used in declarations and in cast expressions (§15.16).
An array type is written as the name of an element type followed by some number of empty pairs of square brackets[]. The number of bracket pairs indicates the depth of array nesting.
Each bracket pair in an array type may be annotated by type annotations (§9.7.4). An annotation applies to the bracket pair (or ellipsis, in a variable arity parameter declaration) that follows it.
The element type of an array may be any type, whether primitive or reference. In particular:
Arrays with an interface type as the element type are allowed.
An element of such an array may have as its value a null reference or an instance of any type that implements the interface.
Arrays with anabstract class type as the element type are allowed.
An element of such an array may have as its value a null reference or an instance of any subclass of theabstract class that is not itselfabstract.
An array's length is not part of its type.
The supertypes of an array type are specified in§4.10.3.
The supertype relation for array types is not the same as the superclass relation. The direct supertype ofInteger[] isNumber[] according to§4.10.3, but the direct superclass ofInteger[] isObject according to theClass object forInteger[] (§10.8). This does not matter in practice, becauseObject is also a supertype of all array types.
A variable of array type holds a reference to an object. Declaring a variable of array type does not create an array object or allocate any space for array components. It creates only the variable itself, which can contain a reference to an array. However, the initializer part of a declarator (§8.3,§9.3,§14.4.1) may create an array, a reference to which then becomes the initial value of the variable.
Example 10.2-1. Declarations of Array Variables
int[] ai; // array of intshort[][] as; // array of array of shortshort s, // scalar short aas[][]; // array of array of shortObject[] ao, // array of Object otherAo; // array of ObjectCollection<?>[] ca; // array of Collection of unknown type
The declarations above do not create array objects. The following are examples of declarations of array variables that do create array objects:
Exception ae[] = new Exception[3];Object aao[][] = new Exception[2][3];int[] factorial = { 1, 1, 2, 6, 24, 120, 720, 5040 };char ac[] = { 'n', 'o', 't', ' ', 'a', ' ', 'S', 't', 'r', 'i', 'n', 'g' };String[] aas = { "array", "of", "String", };The array type of a variable depends on the bracket pairs that may appear as part of the type at the beginning of a variable declaration, or as part of the declarator for the variable, or both. Specifically, in the declaration of a field, formal parameter, local variable, or record component (§8.3,§8.4.1,§9.3,§9.4,§14.4.1,§14.14.2,§15.27.1,§8.10.1), the array type of the variable is denoted by:
the element type that appears at the beginning of the declaration; then,
any bracket pairs that follow the variable'sIdentifier in the declarator (not applicable for a variable arity parameter or a record component); then,
any bracket pairs that appear in the type at the beginning of the declaration (where the ellipsis of a variable arity parameter or variable arity record component is treated as a bracket pair).
The return type of a method (§8.4.5) may be an array type. The precise array type depends on the bracket pairs that may appear as part of the type at the beginning of the method declaration, or after the method's formal parameter list, or both. The array type is denoted by:
We do not recommend "mixed notation" in array variable declarations, where bracket pairs appear on both the type and in declarators; nor in method declarations, where bracket pairs appear both before and after the formal parameter list.
Example 10.2-2. Array Variables and Array Types
The local variable declaration statement:
byte[] rowvector, colvector, matrix[];
is equivalent to:
byte rowvector[], colvector[], matrix[][];
because the array type of each local variable is unchanged. Similarly, the local variable declaration statement:
int a, b[], c[][];
is equivalent to the series of declaration statements:
int a;int[] b;int[][] c;
Brackets are allowed in declarators as a nod to the tradition of C and C++. The general rules for variable declaration, however, permit brackets to appear on both the type and in declarators, so that the local variable declaration statement:
float[][] f[][], g[][][], h[]; // Yechh!
is equivalent to the series of declarations:
float[][][][] f;float[][][][][] g;float[][][] h;
Because of how array types are formed, the following parameter declarations have the same array type:
void m(int @A [] @B [] x) {}void n(int @A [] @B ... y) {}And perhaps surprisingly, the following field declarations have the same array type:
int @A [] f @B [];int @B [] @A [] g;
Once an array object is created, its length never changes. To make an array variable refer to an array of different length, a reference to a different array must be assigned to the variable.
A single variable of array type may contain references to arrays of different lengths, because an array's length is not part of its type.
If an array variablev has typeA[], whereA is a reference type, thenv can hold a reference to an instance of any array typeB[], providedB can be assigned toA (§5.2). This may result in a run-time exception on alater assignment; see§10.5 for a discussion.
An array is created by an array creation expression (§15.10.1) or an array initializer (§10.6).
An array creation expression specifies the element type, the number of levels of nested arrays, and the length of the array for at least one of the levels of nesting. The array's length is available as afinal instance variablelength.
An array initializer creates an array and provides initial values for all its components.
A component of an array is accessed by an array access expression (§15.10.3) that consists of an expression whose value is an array reference followed by an indexing expression enclosed by[ and], as inA[i].
All arrays are0-origin. An array with lengthn can be indexed by the integers0 ton-1.
Example 10.4-1. Array Access
class Gauss { public static void main(String[] args) { int[] ia = new int[101]; for (int i = 0; i < ia.length; i++) ia[i] = i; int sum = 0; for (int e : ia) sum += e; System.out.println(sum); }}This program produces the output:
5050
The program declares a variableia that has type array ofint, that is,int[]. The variableia is initialized to reference a newly created array object, created by an array creation expression (§15.10.1). The array creation expression specifies that the array should have101 components. The length of the array is available using the fieldlength, as shown. The program fills the array with the integers from0 to100, sums these integers, and prints the result.
Arrays must be indexed byint values;short,byte, orchar values may also be used as index values because they are subjected to unary numeric promotion (§5.6) and becomeint values.
An attempt to access an array component with along index value results in a compile-time error.
All array accesses are checked at run time; an attempt to use an index that is less than zero or greater than or equal to the length of the array causes anArrayIndexOutOfBoundsException to be thrown (§15.10.4).
For an array whose type isA[], whereA is a reference type, an assignment to a component of the array is checked at run time to ensure that the value being assigned is assignable to the component.
If the type of the value being assigned is not assignment-compatible (§5.2) with the component type, anArrayStoreException is thrown.
If the component type of an array were not reifiable (§4.7), the Java Virtual Machine could not perform the store check described in the preceding paragraph. This is why an array creation expression with a non-reifiable element type is forbidden (§15.10.1). One may declare a variable of an array type whose element type is non-reifiable, but assignment of the result of an array creation expression to the variable will necessarily cause an unchecked warning (§5.1.9).
Example 10.5-1. ArrayStoreException
class Point { int x, y; }class ColoredPoint extends Point { int color; }class Test { public static void main(String[] args) { ColoredPoint[] cpa = new ColoredPoint[10]; Point[] pa = cpa; System.out.println(pa[1] == null); try { pa[0] = new Point(); } catch (ArrayStoreException e) { System.out.println(e); } }}This program produces the output:
truejava.lang.ArrayStoreException: Point
The variablepa has typePoint[] and the variablecpa has as its value a reference to an object of typeColoredPoint[]. AColoredPoint can be assigned to aPoint; therefore, the value ofcpa can be assigned topa.
A reference to this arraypa, for example, testing whetherpa[1] isnull, will not result in a run-time type error. This is because the element of the array of typeColoredPoint[] is a ColoredPoint, and everyColoredPoint can stand in for aPoint, sincePoint is the superclass ofColoredPoint.
On the other hand, an assignment to the arraypa can result in a run-time error. At compile time, an assignment to an element ofpa is checked to make sure that the value assigned is aPoint. But sincepa holds a reference to an array ofColoredPoint, the assignment is valid only if the type of the value assigned at run time is, more specifically, aColoredPoint.
The Java Virtual Machine checks for such a situation at run time to ensure that the assignment is valid; if not, anArrayStoreException is thrown.
Anarray initializer may be specified in a field declaration (§8.3,§9.3) or local variable declaration (§14.4), or as part of an array creation expression (§15.10.1), to create an array and provide some initial values.
The following production from§8.3 is shown here for convenience:
An array initializer is written as a comma-separated list of expressions, enclosed by braces{ and}.
A trailing comma may appear after the last expression in an array initializer and is ignored.
Each variable initializer must be assignment-compatible (§5.2) with the array's component type, or a compile-time error occurs.
It is a compile-time error if the component type of the array being initialized is not reifiable (§4.7).
The length of the array to be constructed is equal to the number of variable initializers immediately enclosed by the braces of the array initializer. Space is allocated for a new array of that length. If there is insufficient space to allocate the array, evaluation of the array initializer completes abruptly by throwing anOutOfMemoryError. Otherwise, a one-dimensional array is created of the specified length, and each component of the array is initialized to its default value (§4.12.5).
The variable initializers immediately enclosed by the braces of the array initializer are then executed from left to right in the textual order they occur in the source code. Then'th variable initializer specifies the value of then-1'th array component. If execution of a variable initializer completes abruptly, then execution of the array initializer completes abruptly for the same reason. If all the variable initializer expressions complete normally, the array initializer completes normally, with the value of the newly initialized array.
If the component type is an array type, then the variable initializer specifying a component may itself be an array initializer; that is, array initializers may be nested. In this case, execution of the nested array initializer constructs and initializes an array object by recursive application of the algorithm above, and assigns it to the component.
Example 10.6-1. Array Initializers
class Test { public static void main(String[] args) { int[][] ia = { { 1, 2 }, null }; for (int[] ea : ia) { for (int e: ea) { System.out.println(e); } } }}This program produces the output:
12
before causing aNullPointerException in trying to index the second component of the arrayia, which is a null reference.
The members of an array type are all of the following:
Thepublicfinal fieldlength, which contains the number of components of the array.length may be positive or zero.
Thepublic methodclone, which overrides the method of the same name in classObject and throws no checked exceptions. The return type of theclone method of an array typeT[] isT[].
A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.
All the members inherited from classObject; the only method ofObject that is not inherited is itsclone method.
See§9.6.4.4 for another situation where the difference betweenpublic and non-public methods ofObject requires special care.
An array thus has the samepublic fields and methods as the following class:
class A<T> implements Cloneable, java.io.Serializable { public final int length = X; public T[] clone() { try { return (T[])super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(e.getMessage()); } }}Note that the cast toT[] in the code above would generate an unchecked warning (§5.1.9) if arrays were really implemented this way.
Example 10.7-1. Arrays Are Cloneable
class Test1 { public static void main(String[] args) { int[] ia1 = { 1, 2 }; int[] ia2 = ia1.clone(); System.out.print((ia1 == ia2) + " "); ia1[1]++; System.out.println(ia2[1]); }}This program produces the output:
false 2
showing that the components of the arrays referenced byia1 andia2 are different variables.
Example 10.7-2. Shared Subarrays After A Clone
The fact that subarrays are shared when a multidimensional array is cloned is shown by this program:
class Test2 { public static void main(String[] args) throws Throwable { int[][] ia = { { 1, 2 }, null }; int[][] ja = ia.clone(); System.out.print((ia == ja) + " "); System.out.println(ia[0] == ja[0] && ia[1] == ja[1]); }}This program produces the output:
false true
showing that theint[] array that isia[0] and theint[] array that isja[0] are the same array.
Every array has an associatedClass object, shared with all other arrays with the same component type.
Although an array type is not a class, theClass object of every array acts as if:
Example 10.8-1. Class Object Of Array
class Test1 { public static void main(String[] args) { int[] ia = new int[3]; System.out.println(ia.getClass()); System.out.println(ia.getClass().getSuperclass()); for (Class<?> c : ia.getClass().getInterfaces()) System.out.println("Superinterface: " + c); }}This program produces the output:
class [Iclass java.lang.ObjectSuperinterface: interface java.lang.CloneableSuperinterface: interface java.io.Serializable
where the string "[I" is the run-time type signature for theClass object "array with component typeint".
Example 10.8-2. ArrayClass Objects Are Shared
class Test2 { public static void main(String[] args) { int[] ia = new int[3]; int[] ib = new int[6]; System.out.println(ia == ib); System.out.println(ia.getClass() == ib.getClass()); }}This program produces the output:
falsetrue
Whileia andib refer to different arrays, the result of the comparison of theClass objects demonstrates that all arrays whose components are of typeint are instances of the same array type (namelyint[]).
In the Java programming language, unlike C, an array ofchar is not aString, and neither aString nor an array ofchar is terminated by '\u0000' (the NUL character).
AString object is immutable, that is, its contents never change, while an array ofchar has mutable elements.
The methodtoCharArray in classString returns an array of characters containing the same character sequence as aString. The classStringBuffer implements useful methods on mutable arrays of characters.