Spec-Zone .ru
спецификации, руководства, описания, API
Содержание | Предыдущий | Следующий | Индекс Спецификация языка Java
Третий Выпуск


ГЛАВА 10

Массивы


В Java массивы языка программирования являются объектами (§4.3.1), динамически создаются, и могут быть присвоены переменным типа Object (§4.3.2). Все методы класса Object может быть вызван на массив.

Объект массива содержит много переменных. Число переменных может быть нулем, когда массив, как говорят, пуст. У переменных, содержавшихся в массиве, нет никаких имен; вместо этого на них ссылаются выражения доступа массива, которые используют неотрицательные целочисленные индексные значения. Эти переменные вызывают компонентами массива. Если у массива есть n компоненты, мы говорим, что n является длиной массива; на компоненты массива ссылаются, используя целочисленные индексы от 0 до n-1, включительно.

У всех компонентов массива есть тот же самый тип, названный компонентным типом массива. Если компонентный тип массива является T, то тип самого массива пишется T [].

Значение компонента массива типа float всегда элемент набора значений плавающего (§4.2.3); точно так же значение компонента массива типа double всегда элемент двойного набора значений. Это не разрешается для значения компонента массива типа float чтобы быть элементом набора значений "пускают в ход расширенную экспоненту", которая не является также элементом набора значений плавающего, ни для значения компонента массива типа double чтобы быть элементом набора значений "удваивают расширенную экспоненту", которая не является также элементом двойного набора значений.

Компонентный тип массива может самостоятельно быть типом массива. Компоненты такого массива могут содержать ссылки на подмассивы. Если, запускаясь с какого-либо типа массива, каждый рассматривает его компонентный тип, и затем (если это - также тип массива), компонентный тип того типа, и так далее, в конечном счете нужно достигнуть компонентного типа, который не является типом массива; это вызывают типом элемента исходного массива, и компоненты на этом уровне структуры данных вызывают элементами исходного массива.

Есть некоторые ситуации, в которых элемент массива может быть массивом: если тип элемента Object или Cloneable или java.io.Serializable, тогда некоторые или все элементы могут быть массивами, потому что любой объект массива может быть присвоен любой переменной этих типов.

10.1 Типы массива

Тип массива пишется как имя типа элемента, сопровождаемого некоторым числом пустых пар квадратных скобок []. Число пар скобки указывает на глубину вложения массива. Длина массива не является частью своего типа.

Тип элемента массива может быть любым типом, или примитивный или ссылочный. В особенности:

Типы массива используются в объявлениях и в выражениях броска (§15.16).

10.2 Переменные типа массив

Переменная типа массива содержит ссылку на объект. Объявление переменной типа массива не создает объект массива или выделяет любое место для компонентов массива. Это создает только переменную непосредственно, которая может содержать ссылку на массив. Однако, часть инициализатора оператора объявления (§8.3) может создать массив, ссылку, к которой тогда становится начальным значением переменной.

Поскольку длина массива не является частью своего типа, единственная переменная типа массива может содержать ссылки на массивы различных длин.

Вот примеры объявлений переменных типа массив, которые не создают массивы:

int[] ai;			// array of int
short[][] as;			// array of array of short
Object[]	ao,		// array of Object
		otherAo;	// array of Object
Collection<?>[] ca;		// array of Collection of unknown type
short		s,		// scalar short 
		aas[][];	// array of array of short
Вот некоторые примеры объявлений переменных типа массив, которые создают объекты массива:

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", };

[] может появиться как часть типа в начале объявления, или как часть оператора объявления для определенной переменной, или обоих, как в этом примере:

byte[] rowvector, colvector, matrix[];
Это объявление эквивалентно:

byte rowvector[], colvector[], matrix[][];
Как только объект массива создается, его длина никогда не изменяется. Чтобы заставить переменную типа массив обратиться к массиву различной длины, ссылка на различный массив должна быть присвоена переменной.

Если у переменной типа массив v есть тип A [], где A является ссылочным типом, то v может содержать ссылку на экземпляр любого типа B массива [], обеспечил, B может быть присвоен A. Это может привести к исключению на этапе выполнения на более позднем присвоении; см. §10.10 для обсуждения.

10.3 Создание массива

Массив создается выражением создания массива (§15.10) или инициализатор массива (§10.6).

Выражение создания массива определяет тип элемента, число уровней вложенных массивов, и длины массива для по крайней мере одного из уровней вложения. Длина массива доступна как заключительная переменная экземпляра length. Это - ошибка времени компиляции, если тип элемента не является типом reifiable (§4.7)

Инициализатор массива создает массив и обеспечивает начальные значения для всех его компонентов.

10.4 Доступ массива

К компоненту массива получает доступ выражение доступа массива (§15.13), который состоит из выражения, значение которого является ссылкой массива, сопровождаемой выражением индексации, включенным [ и ], как в A[i]. Все массивы 0- источник. Массив с длиной n может быть индексирован целыми числами 0 к n-1.

Массивы должны быть индексированы int значения; short, byte, или char значения могут также использоваться в качестве индексных значений, потому что они подвергаются унарному числовому продвижению (§) и становятся int значения. Попытка получить доступ к компоненту массива с a long индексируйте результаты значения в ошибке времени компиляции.

Во время выполнения проверяются все доступы массива; попытка использовать индекс, который является меньше чем нуль или больше чем или равный длине массива, вызывает ArrayIndexOutOfBoundsException быть брошенным.

10.5 Массивы: Простой Пример

Пример:

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);
	}
}
это производит вывод:

5050
объявляет переменную ia у этого есть массив типа int, то есть, int[]. Переменная ia инициализируется, чтобы сослаться на недавно создаваемый объект массива, создаваемый выражением создания массива (§15.10). Выражение создания массива определяет, что массив должен иметь 101 компоненты. Длина массива является доступным использованием поля length, как показано.

Пример программы заполняет массив целыми числами от 0 к 100, суммы эти целые числа, и печатные издания результат.

10.6 Инициализаторы массива

Инициализатор массива может быть определен в объявлении, или как часть выражения создания массива (§15.10), создавая массив и обеспечивая некоторые начальные значения:


ArrayInitializer:
	{ VariableInitializersopt ,opt }

VariableInitializers:
	VariableInitializer
	VariableInitializers , VariableInitializer
	
Следующее повторяется от §8.3, чтобы сделать представление здесь более четким:


VariableInitializer:
	Expression
	ArrayInitializer
	
Инициализатор массива пишется как список разделенных запятой значений выражений, включенных фигурными скобками"{"и"}".

Длина созданного массива будет равняться числу выражений.

Выражения в инициализаторе массива выполняются слева направо в текстовом порядке, они происходят в исходном коде. Энный переменный инициализатор определяет значение компонента массива n-1st. Каждое выражение должно быть совместимым с присвоением (§5.2) с компонентным типом массива, или ошибка времени компиляции заканчивается. Это - ошибка времени компиляции, если компонентный тип инициализируемого массива не является reifiable (§4.7).

Если компонентный тип является самостоятельно типом массива, то выражение, определяющее компонент, может самостоятельно быть инициализатором массива; то есть, инициализаторы массива могут быть вложены.

Запаздывающая запятая может появиться после последнего выражения в инициализаторе массива и игнорируется.

Как пример:

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);
	}
}
печатные издания:

1
2
прежде, чем вызвать a NullPointerException в попытке индексировать второй компонент массива ia, который является нулевой ссылкой.

10.7 Элементы массива

Элементы типа массива являются всем следующим:

У массива таким образом есть те же самые общедоступные поля и методы как следующий класс:

class A<T> implements Cloneable, java.io.Serializable {
	public final int length = X;
	public T[] clone() {
		try {
			return (T[])super.clone(); // unchecked warning
		} catch (CloneNotSupportedException e) {
			throw new InternalError(e.getMessage());
		}
	}
}
Отметьте, что бросок в примере выше генерировал бы предупреждение непроверенное (§5.1.9), если бы массивы были действительно реализованы этот путь.

Каждый массив реализует интерфейсы Cloneable и java.io.Serializable.

Это выстраивает, cloneable, показывается тестовой программой:

class Test {
	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]);
	}
}
который печатает:

false 2
показ, что компоненты массивов, на которые ссылаются ia1 и ia2 различные переменные. (В некоторых ранних реализациях языка программирования Java этот пример, отказавший, чтобы скомпилировать, потому что компилятор, которому неправильно полагают, что метод клона для массива мог бросить a CloneNotSupportedException.)

A clone из многомерного массива мелко, который должен сказать, что создает только единственный новый массив. Подмассивы совместно используются.

Это показывает пример программы:

class Test {
	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]);
	}
}
который печатает:

false true
показ, что int[] массив, который является ia[0] и int[] массив, который является ja[0] тот же самый массив.

10.8 Объекты класса для Массивов

У каждого массива есть связанное Class объект, совместно использованный со всеми другими массивами с тем же самым компонентным типом. Прямой суперкласс типа массива Object. Каждый тип массива реализует интерфейсы Cloneable и java.io.Serializable.

Это показывает следующий пример кода:

class Test {
	public static void main(String[] args) {
		int[] ia = new int[3];
		System.out.println(ia.getClass());
		System.out.println(ia.getClass().getSuperclass());
	}
}
который печатает:

class [I
class java.lang.Object
где строка"[I"подпись типа времени выполнения для массива "объекта класса с компонентным типом int".

10.9 Массивом Символов Не является Строка

В языке программирования Java, в отличие от C, массива char не a String, и ни один a String ни массив char завершается '\u0000' (символ NUL).

A String объект является неизменным, то есть, его содержание никогда не изменяется, в то время как массив char имеет изменчивые элементы. Метод toCharArray в классе String возвращает массив символов, содержащих ту же самую символьную последовательность как a String. Класс StringBuffer реализует полезные методы на изменчивых массивах символов.

10.10 Исключений Хранилища Массива

Если у переменной типа массив v есть тип A [], где A является ссылочным типом, то v может содержать ссылку на экземпляр любого типа B массива [], обеспечил, B может быть присвоен A.

Таким образом, пример:

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);
		}
	}
}
производит вывод:

true
java.lang.ArrayStoreException
Здесь переменная pa имеет тип Point[] и переменная cpa имеет как его значение ссылка на объект типа ColoredPoint[]. A ColoredPoint может быть присвоен a Point; поэтому, значение cpa может быть присвоен pa.

Ссылка на этот массив pa, например, тестирование, ли pa[1] null, не будет приводить к ошибке типа времени выполнения. Это то, потому что элемент массива типа ColoredPoint[] a ColoredPoint, и каждый ColoredPoint может помочь для a Point, с тех пор Point суперкласс ColoredPoint.

С другой стороны, присвоение на массив pa может привести к ошибке периода выполнения. Во время компиляции, присвоение на элемент pa проверяется, чтобы удостовериться, что присвоенное значение является a Point. Но с тех пор pa содержит ссылку на массив ColoredPoint, присвоение допустимо, только если тип значения, присвоенного во время выполнения, более определенно, a ColoredPoint.

Виртуальная машина Java проверяет на такую ситуацию во время выполнения, чтобы гарантировать, что присвоение допустимо; в противном случае ArrayStoreException бросается. Более формально: присвоение на элемент массива, тип которого [], где A является ссылочным типом, проверяется во время выполнения, чтобы гарантировать, что присвоенное значение может быть присвоено фактическому типу элемента массива, где фактический тип элемента может быть любым ссылочным типом, который присваиваем A.


Обсуждение

Если бы тип элемента массива не был reifiable (§4.7), то виртуальная машина не могла бы выполнить проверку хранилища, описанную в предыдущем абзаце. Это - то, почему создание массивов типов non-reifiable запрещается. Можно объявить переменные типов массива, тип элемента которых не является reifiable, но любой попыткой присвоить их, значение даст начало предупреждению непроверенному (§5.1.9).



Содержание | Предыдущий | Следующий | Индекс Спецификация языка Java
Третий Выпуск

Авторское право © 1996-2005 Sun Microsystems, Inc. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления через нашу форму обратной связи

free hit counter