Кен Арнольд Джеймс Гослинг

Вид материалаДокументы

Содержание


5.8.1. Многомерные массивы
5.9.1. Инициализация массивов
Подобный материал:
1   ...   24   25   26   27   28   29   30   31   ...   81

5.8. Массивы


Массив представляет собой упорядоченный набор элементов. Элементы массива могут иметь примитивный тип или являться ссылками на объекты, в том числе и ссылками на другие массивы. Строка

int[] ia = new int[3];

объявляет массив с именем ia, в котором изначально хранится три значения типа int.

При объявлении переменной-массива размер не указывается. Количество элементов в массиве задается при его создании оператором new, а не при объявлении. Размер объекта-массива фиксируется в момент его создания и не может изменяться в дальнейшем. Обратите внимание: фиксируется именно размер объекта-массива; в приведенном выше примере ia может быть присвоена ссылка на любой массив другого размера.

Первый элемент массива имеет индекс 0 (ноль), а последний — индекс размер–1. В нашем примере последним элементом массива является ia[2]. При каждом использовании индекса проверяется, лежит ли он в диапазоне допустимых значений. При выходе индекса за его пределы возбуждается исключение IndexOutOfBounds.

Размер массива можно получить из поля length. Для нашего примера следующий фрагмент программы перебирает все элементы массива и выводит каждое значение:

for (int i =0; i << ia.length; i++)

System.out.println(i + ": " + ia[i]);

Массивы всегда являются неявным расширением класса Object. Если у вас имеется класс X, расширяющий его класс Y и массивы каждого из этих классов, то иерархия будет выглядеть следующим образом:



Благодаря этому обстоятельству массивы ведут себя полиморфно. Вы можете присвоить массив переменной типа Object, после чего осуществить обратное преобразование. Массив объектов типа Y допускается использовать всюду, где разрешено присутствие массива объектов базового типа X.

Как и к любым другим созданным объектам, к массивам применяется сборка мусора.

Основное ограничение на “объектность” массивов заключается в том, что они не могут расширяться для включения в них новых методов. Так, следующая конструкция является недопустимой:

class ScaleVector extends double[] { //

// ...

}

При объявлении массива объектов вы на самом деле объявляете массив переменных соответствующего типа. Рассмотрим следующий фрагмент:

Attr[] attrs = new Attr[12];


for (int i = 0; i << attrs.length; i++)

attrs[i] = new Attr(names[i], values[i]);

После выполнения первого оператора new, attrs содержит ссылку на массив из 12 переменных, инициализированных значением null. Объекты Attr создаются только при выполнении цикла.

Если вы пожелаете, Java допускает присутствие квадратных скобок после переменной, а не после типа, как в следующем объявлении:

int ia[] = new int[3];

Оно эквивалентно приведенному выше. Тем не менее первый вариант все же считается более предпочтительным, поскольку тип объявляется в одном месте.

5.8.1. Многомерные массивы


Элементами массивов в Java могут быть другие массивы. Например, фрагмент программы для объявления и вывода двумерной матрицы может выглядеть следующим образом:

float[][] mat = new float[4][4];

setupMatrix(mat);

for (int y = 0; y << mat.length; y++) {

for (int x = 0; x << mat[y].length; x++)

System.out.println(mat[x][y] + " ");

System.out.println();

}

Первый (левый) размер массива должен задаваться при его создании. Другие размеры могут указываться позже. Использование более чем одной размерности является сокращением для вложенного набора операторов new. Приведенный выше массив может быть создан следующим образом:

float[][] mat = new float[4][];

for (int y = 0; y << mat.length; y++)

mat[y] = new float[4];

Одно из преимуществ многомерных массивов состоит в том, что каждый вложенный массив может иметь свои размеры. Вы можете имитировать работу с массивом 4x4, но при этом создать массив из четырех массивов типа int, каждый из которых имеет свою собственную длину, необходимую для хранения его данных.

Упражнение 5.1

Напишите программу, которая строит треугольник Паскаля до глубины 12. Каждый числовой ряд треугольника сохраняется в массиве соответствующей длины, а массивы рядов заносятся в массив, элементами которого являются 12 массивов типа int. Спроектируйте свое решение так, чтобы результаты выводились методом, который печатает содержимое двумерного массива с использованием длины каждого из вложенных массивов, а не константы 12. Теперь модифицируйте программу так, чтобы в ней использовалась константа, отличная от 12, а метод вывода при этом не изменился.

5.9. Инициализация


Переменная может инициализироваться при ее объявлении. Чтобы задать начальное значений переменной, следует после ее имени поставить = и выражение:

final double p = 3.14159;

float radius = 1.0f; // начать с единичного радиуса

Если при объявлении поля класса не инициализируются, то Java присваивает им исходные значения по умолчанию. Значение по умолчанию зависит от типа поля:

Тип поля

Тип поля

boolean

false

char

‘\u0000’

целое (byte, short, int, long)

0

с плавающей точкой

+0.0f или +0.0d

ссылка на объект

null

Java не присваивает никаких исходных значений локальным переменным метода, конструктора или статического инициализатора. Отсутствие исходного значения у локальной переменной обычно представляет собой программную ошибку, и перед использованием локальных переменных их необходимо инициализировать.

Момент инициализации переменной зависит от ее области видимости. Локальные переменные инициализируются каждый раз, когда выполняется их объявление. Поля объектов и элементы массивов инициализируются при создании объекта или массива оператором new — см. “Порядок вызова конструкторов”. Инициализация статических переменных класса происходит перед выполнением какого-либо кода, относящегося к данному классу.

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

5.9.1. Инициализация массивов


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

String[] dangers = { "Lions", "Tigers", "Bears" };

Это равносильно следующему фрагменту:

String[] dangers = new String[3];


dangers[0] = "Lions";

dangers[1] = "Tigers";

dangers[2] = "Bears";

Для инициализации многомерных массивов может использоваться вложение инициализаторов отдельных массивов. Приведем объявление, в котором инициализируется матрица размеров 4x4:

double[][] identityMatrix = {

{ 1.0, 0.0, 0.0, 0.0 },

{ 0.0, 1.0, 0.0, 0.0 },

{ 0.0, 0.0, 1.0, 0.0 },

{ 0.0, 0.0, 0.0, 1.0 },

};