Перейти на главную   
  helloworld.ru - документация и книги по программированию  
helloworld.ru - документация и книги по программированию
    главная     хостинг    
Поиск по сайту:  
Смотрите также
Языки программирования
C#
MS Visual C++
Borland C++
C++ Builder
Visual Basic
Quick Basic
Turbo Pascal
Delphi
JavaScript
Java
PHP
Perl
Assembler
AutoLisp
Fortran
Python
1C

Интернет-технологии
HTML
VRML
HTTP
CGI
FTP
Proxy
DNS
протоколы TCP/IP
Apache

Web-дизайн
HTML
Дизайн
VRML
PhotoShop
Cookie
CGI
SSI
CSS
ASP
PHP
Perl

Программирование игр
DirectDraw
DirectSound
Direct3D
OpenGL
3D-графика
Графика под DOS

Алгоритмы
Численные методы
Обработка данных

Сис. программирование
Драйверы

Базы данных
MySQL
SQL

Другое

Хостинг


Друзья
demaker.ru
Реклама

Лучший хостинг. Аренда серверов




helloworld.ru

ГЛАВА 10. Массивы

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

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

Все компоненты массива имеют одинаковый тип, который называется типом компонент массива. Если тип компонент массива - T, тогда массив пишется T [].

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

Существует ситуация, в которой элемент массива может быть массивом: если тип элемента - Object, тогда некоторый, или все элементы могут быть массивами, потому что любой объект массива может быть присвоен любой переменной типа Object .

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

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

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

  • Разрешается массив с интерфейсным типом таким, как тип компонент . Элементы такого массива могут иметь значением пустую ссылку (null) или экземпляры любого классового типа, который реализует интерфейс.
  • Разрешается массив с классовым типом abstract как тип компонент. Элементы такого массива могут иметь значением - пустую ссылку (null) или экземпляры любого подкласса класса abstract, который сам не abstract.

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

10.2 Переменные-массивы

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

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

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


int[] ai;							// массив типа int
short[][] as;							// массив из массивов типа short
Object[]			ao,				// массив типа Object
			otherAo;				// массив типа Object
short		s,					// скаляр short 
		aas[][];					// массив из массивов типа 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.9) или инициализатором массива (§10.6).

Выражение создания массива определяет тип элемента, число уровней вложенных массивов, и длину массива, по крайней мере одного из уровней вложения. Длина массива доступна как конечный экземпляр переменной length.

Инициализатор массива создает массив и обеспечивает начальные значения для всех компонент (Это контраст по сравнению с Cи и Cи ++, где это возможно для инициализатора массива, определяющего начальные значения для некоторых но не всех компонент массива.)

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

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

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

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

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 i = 0; i < ia.length; i++)
			sum += ia[i];
		System.out.println(sum);
	}
}

который вывод:

5050

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

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

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

    ArrayInitializer:
    
    	{ VariableInitializersopt ,opt }
    
    VariableInitializers:
    
    	VariableInitializer
    
    	VariableInitializers , VariableInitializer
    

Для большей ясности следующее повторяется из §8.3:

    VariableInitializer:
    
    	Expression
    
    	ArrayInitializer
    

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

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

Каждое выражение определяет значение для одного компонента массива. Каждое выражение должно быть совместимо по присваиванию (§5.2) с типом компонент массива, или происходит ошибка времени компиляции.

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

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

Как в примере:


class Test {
	public static void main(String[] args) {
		int ia[][] = { {1, 2}, null };
		for (int i = 0; i < 2; i++)
			for (int j = 0; j < 2; j++)
				System.out.println(ia[i][j]);
	}
}

который выводит:


1
2

до возникновения NullPointerException при попытке индексирования второго компонента массива ia, который равен null.

10.7 Члены массива

Члены массива следующее:

  • public final поле length (длина), которое содержит число компонентов массива (length (длина) может быть только неотрицательной)
  • public метод clone, который переопределяет метод того же имени в классе Оbject и не генерирует контролируемых исключительных ситуаций.
  • Все члены, унаследованные от класса Object; только метод из Object не унаследуется clone.

Массив таким образом имеет те же самые методы что и следующий класс


class A implements Cloneable {
	public final int length = X;
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			throw new InternalError(e.getMessage());
		}
	}

}

Каждые массив реализуется иньтерфейсом Cloneable. Эти массивы являются cloneable, как показано в тестирующей программе:


class Test {
	public static void main(String[] args) {
		int ia1[] = { 1, 2 };
		int ia2[] = (int[])ia1.clone();
		System.out.print((ia1 == ia2) + " ");
		ia1[1]++;
		System.out.println(ia2[1]);
	}
}

Которая выводит:

false 2

и которая показывает что компоненты массивов, обозначенных через ia1 и ia2, являются различными переменными. (В некоторых ранних реализациях языка Ява этот пример сбивается при компиляции, потому что компилятор неверно полагал, что метод clone для массива может генерировать CloneNotSupportedException.)

Метод сlone многомерного массива создает только одномерный новый массив. Подмассивы оказываются общими, как показано в примере программы :


class Test {
	public static void main(String[] args) throws Throwable {
		int ia[][] = { { 1 , 2}, null };
		int ja[][] = (int[][])ia.clone();
		System.out.print((ia == ja) + " ");
		System.out.println(ia[0] == ja[0] && ia[1] == ja[1]);
	}
}

Который выводит:

false true

и показывает, что массивы типа int[], которыми являются ia[0] и ja[0] - это один и тот же массив.

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

Каждый массив имеет связанный объект Class, разделяемый со всеми другими массивами, имеющими тот же самый тип компонент. Суперкласс типа-массива рассматривается как Object, что видно из следующего примера:


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" (§20.1.1).

10.9 Массив символов - не String

В языке Ява, в отличие от Cи, массив типа char - не String (§20.12), и ни строка, ни массив типа char не заканчиваются ‘\u0000‘ (символом NUL).

Объект String языка Ява не меняется, то есть никогда не меняется его содержание, в то время как массив типа char имеет непостоянные элементы. Метод toCharArray в классе String, возвращает массив символов, содержащий одинаковую последовательность символов, такую как String. Класс StringBuffer реализует полезные методы для непостоянных массивов символов (§20.13).

10.10 Исключение сохранения массива

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

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


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[]. ColoredPoint может присваиваться Point; поэтому значение cpa может быть присвоено pa.

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

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

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


[ Назад | Оглавление | Далее ]










helloworld.ru © 2001-2018
Все права защищены
Rambler's Top100 TopList