44

44


}

Cups О {

printCCupsO");

}

}

public class ExplicitStatic {

public static void main(String[] args) { printCInside mainO"); Cups.cupl.f(99); II (1)

}

II static Cups cupsl = new CupsO; II (2) II static Cups cups2 = new CupsO, II (2)

} /* Output: Inside mainO Cup(l) Cup(2) f (99) *///:-

Статический инициализатор класса Cups выполняется либо при обращении к статическому объекту cl в строке с пометкой (1), либо если строка (1) заком¬ментирована — в строках (2) после снятия комментариев. Если же и строка (1), и строки (2) закомментированы, static-инициализация класса Cups никогда не выполнится. Также неважно, будут ли исполнены одна или обе строки (2) программы — static-инициализация все равно выполняется только один раз.

Инициализация нестатических данных экземпляра

В Java имеется сходный синтаксис для инициализации нестатических перемен¬ных для каждого объекта. Вот пример: .

// initialization/Mugs java // "Инициализация экземпляра" в Java import static net mindview util.Print *.

class Mug {

Mug(int marker) {

print("Mug(" + marker + ")");

}

void f(int marker) {

print("f(" + marker + ")");

}

}

public class Mugs { Mug mugl.

Mug mug2, {

mugl = new Mug(l); mug2 = new Mug(2).

print("mugl & mug2 инициализированы");

}

Mugs О {

print("Mugs()");

}

Mugs(int i) {

print("Mugs(int)"),

}

public static void main(String[] args) { printC'B методе mainO"); new Mugs О,

print("new Mugs О завершено"), new Mugs(l),

print("new Mugs(l) завершено");

}

} /* Output. В методе mainO Mug(l)

Mug(2) продолжение &

mugl & mug2 инициализированы Mugs О

new Mugs О завершено

Mug(1)

Mug(2)

mugl & mug2 инициализированы Mugs(int)

new Mugs(l) завершено *///:-

Секция инициализации экземпляра

{

mugl = new Mug(l);

mug2 = new Mug(2);

print("mugl & mug2 инициализированы");

}

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

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

Массив представляет собой последовательность объектов или примитивов, от¬носящихся к одному типу, обозначаемую одним идентификатором. Массивы определяются и используются с помощью оператора индексирования [ ]. Чтобы объявить массив, вы просто. указываете вслед за типом пустые квадратные скобки:

int[] al;

Квадратные скобки также могут размещаться после идентификатора, эф¬фект будет точно таким же:

int al[];

Это соответствует ожиданиям программистов на С и С++, привыкших к та¬кому синтаксису. Впрочем, первый стиль, пожалуй, выглядит более логично — он сразу дает понять, что имеется в виду «массив значений типа int». Он и бу¬дет использоваться в книге.

Компилятор не позволяет указать точный размер массива. Вспомните, что говорилось ранее о ссылках. Все, что у вас сейчас есть, — это ссылка на массив, для которого еще не было выделено памяти. Чтобы резервировать память для массива, необходимо записать некоторое выражение инициализации. Для мас¬сивов такое выражение может находиться в любом месте программы, но суще¬ствует и особая разновидность выражений инициализации, используемая толь¬ко в точке объявления массива. Эта специальная инициализация выглядит как набор значений в фигурных скобках. Выделение памяти (эквивалентное дейст¬вию оператора new) в этом случае проводится компилятором. Например:

int[] al = { 1, 2. 3, 4. 5 }.

Но зачем тогда вообще нужно определять ссылку на массив без самого мас¬сива?

int[] а2,

Во-первых, в Java можно присвоить один массив другому, записав сле¬дующее:

а2 = al,

В данном случае вы на самом деле копируете ссылку, как показано в при¬мере:

// initialization/ArraysOfPrimitives.java

// Массивы простейших типов.

import static net mindview.util.Print.*;

public class ArraysOfPrimitives {

public static void main(String[] args) { int:: al = { 1. 2, 3. 4, 5 }: int[] a2; a2 = al.

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

a2[i] = a2[i] + 1; for(int i = 0; i < al.length; i++)

print("al[" + i +"]=" + al[i]);

}

} /* Output: al[0] = 2 al[l] = 3 al[2] = 4 al[3] = 5 al[4] = 6 *///:-

Массив al инициализируется набором значений, в то время как массив а2 — нет; присваивание по ссылке а2 присваивается позже — в данном случае при¬сваивается другой массив.

Все массивы (как массивы примитивов, так и массивы объектов) содержат поле> которое можно прочитать (но не изменить!) для получения количества элементов в массиве. Это поле называется length. Так как в массивах Java, С и С++ .нумерация элементов начинается с нуля, последнему элементу массива соответстйует индекс length—1. При выходе за границы массива С и С++ не пре¬пятствуют «прогулкам в памяти» программы, что часто приводит к печальным последствиям. Но Java защищает вас от таких проблем — при выходе за рамки массива происходит ошибка времени исполнения (исключение, тема главы 10) .

А если во время написания программы вы не знаете, сколько элементов вам понадобится в новом массиве? Тогда просто используйте new для создания его элементов. В следующем примере new работает, хотя в программе создается массив примитивных типов (оператор new неприменим для создания примити¬вов вне массива):

//: initialization/ArrayNew.java // Создание массивов оператором new. import java util.*;

import static net.mindview util.Print *;

public class ArrayNew {

public static void main(String[] args) { int[] a.

Random rand = new Random(47); a = new int[rand.nextlnt(20)]; print("Длина a = " + a length), print(Arrays.toString(a));

}

} /* Output- Длина a = 18

[0, 0. 0, 0. 0, 0, 0, 0, 0, 0. 0, 0. 0. 0. 0, 0. 0. 0] *///-

Размер массива выбирается случайным образом, с использованием метода Random.nextlnt(), генерирующего число от нуля до переданного в качестве аргу¬мента значения. Так как размер массива случаен, очевидно, что создание масси¬ва происходит во время исполнения программы. Вдобавок, результат работы программы позволяет убедиться в том, что элементы массивов простейших ти¬пов автоматически инициализируются «пустыми» значениями. (Для чисел и символов это ноль, а для логического типа boolean — false.)

Report Page