CHAPTER 15: Expressions Previous
Previous
Java Language
Java Language
Index
Index
Next
Next

15.9 Array Creation Expressions

15.9.1 Run-time Evaluation of Array Creation Expressions , 15.9.2 Example: Evaluation Order , 15.9.3 Example: Evaluation Order and Out-of-Memory Detection

An array instance creation expression is used to create new arrays (Chapter 10).


ArrayCreationExpression:

	new PrimitiveType DimExprs Dimsopt

	new TypeName DimExprs Dimsopt

DimExprs:

	DimExpr

	DimExprs DimExpr

DimExpr:

	[ Expression ]

Dims:

	[ ]

	Dims [ ]

An array creation expression creates an object that is a new array whose elements are of the type specified by the PrimitiveType or TypeName. The TypeName may name any reference type, even an abstract class type (S8.1.2.1) or an interface type (Chapter 9).

The type of the creation expression is an array type that can denoted by a copy of the creation expression from which the new keyword and every DimExpr expression have been deleted; for example, the type of the creation expression:

new double[3][3][]

is:

double[][][]

The type of each dimension expression DimExpr must be an integral type, or a compile-time error occurs. Each expression undergoes unary numeric promotion (S5.6.1). The promoted type must be int , or a compile-time error occurs; this means, specifically, that the type of a dimension expression must not be long .


15.9.1 Run-time Evaluation of Array Creation Expressions

At run time, evaluation of an array creation expression behaves as follows.

First, the dimension expressions are evaluated, left-to-right. If any of the expression evaluations completes abruptly, the expressions to the right of it are not evaluated.

Next, the values of the dimension expressions are checked. If the value of any DimExpr expression is less than zero, then an NegativeArraySizeException is thrown.

Next, space is allocated for the new array. If there is insufficient space to allocate the array, evaluation of the array creation expression completes abruptly by throwing an OutOfMemoryError .

Then, if a single DimExpr appears, a single-dimensional array is created of the specified length, and each component of the array is initialized to its standard default value (S4.5.4).

If an array creation expression contains N DimExpr expressions, then it effectively executes a set of nested loops of depth N - 1 to create the implied arrays of arrays. For example, the declaration:

float[][] matrix = new float[3][3];

is equivalent in behavior to:


float[][] matrix = new float[3][];
for (int d = 0; d < matrix.length; d++)
	matrix[d] = new float[3];

and:

Age[][][][][] Aquarius = new Age[6][10][8][12][];

is equivalent to:


Age[][][][][] Aquarius = new Age[6][][][][];
for (int d1 = 0; d1 < Aquarius.length; d1++) {
	Aquarius[d1] = new Age[8][][][];
	for (int d2 = 0; d2 < Aquarius[d1].length; d2++) {
		Aquarius[d1][d2] = new Age[10][][];
		for (int d3 = 0; d3 < Aquarius[d1][d2].length; d3++) {
			Aquarius[d1][d2][d3] = new Age[12][];
		}
	}
}

with d, d1, d2 and d3 replaced by names that are not already locally declared. Thus, a single new expression actually creates one array of length 6, 6 arrays of length 10, 6 ´ 10 = 60 arrays of length 8, and 6 ´ 10 ´ 8 = 480 arrays of length 12. This example leaves the fifth dimension, which would be arrays containing the actual array elements (references to Age objects), initialized only to null references. These arrays can be filled in later by other code, such as:


Age[] Hair = { new Age("quartz"), new Age("topaz") };
Aquarius[1][9][6][9] = Hair;

A multidimensional array need not have arrays of the same length at each level; thus, a triangular matrix may be created by:


float triang[][] = new float[100][];
for (int i = 0; i < triang.length; i++)
	triang[i] = new float[i+1];

There is, however, no way to get this effect with a single creation expression.


15.9.2 Example: Evaluation Order

In an array creation expression (S15.9), there may be one or more dimension expressions, each within brackets. Each dimension expression is fully evaluated before any part of any dimension expression to its right.

Thus:


class Test {
	public static void main(String[] args) {
		int i = 4;
		int ia[][] = new int[i][i=3];
		System.out.println(
			"[" + ia.length + "," + ia[0].length + "]");
	}
}

prints:

[4,3]

because the first dimension is calculated as 4 before the second dimension expression sets i to 3 .

If evaluation of a dimension expression completes abruptly, no part of any dimension expression to its right will appear to have been evaluated. Thus, the example:


class Test {

	public static void main(String[] args) {
		int[][] a = { { 00, 01 }, { 10, 11 } };
		int i = 99;
		try {
			a[val()][i = 1]++;
		} catch (Exception e) {
			System.out.println(e + ", i=" + i);
		}
	}

	static int val() throws Exception {
		throw new Exception("unimplemented");
	}

}

prints:

java.lang.Exception: unimplemented, i=99

because the embedded assignment that sets i to 1 is never executed.


15.9.3 Example: Evaluation Order and Out-of-Memory Detection

If evaluation of an array creation expression finds there is insufficient memory to perform the creation operation, then an OutOfMemoryError is thrown. This check occurs only after evaluation of all dimension expressions has completed normally.

So, for example, the test program:


class Test {
	public static void main(String[] args) {
		int len = 0, oldlen = 0;
		Object[] a = new Object[0];
		try {
			for (;;) {
				++len;
				Object[] temp = new Object[oldlen = len];
				temp[0] = a;
				a = temp;
			}
		} catch (Error e) {
			System.out.println(e + ", " + (oldlen==len));
		}
	}
}

prints:

java.lang.OutOfMemoryError, true

because the out-of-memory condition is detected after the argument expression oldlen = len is evaluated.

Compare this to class instance creation expressions (S15.8), which detect the out-of-memory condition before evaluating argument expressions (S15.8.2).

Top© 1996 Sun Microsystems, Inc. All rights reserved.