Эккель Брюс
Шрифт:
new Beryl 1iumSphere. new BerylliumSphereO
}.
// Динамическая агрегатная инициализация a = new BerylliumSphere[]{
new Beryl liumSphereO. new Beryl liumSphereO.
}.
// (Завершающая запятая не обязательна в обоих случаях)
print("a.length = " + a length);
printC'b.length = " + b length),
printC'c length = " + с length),
printed length = " + d length);
a = d,
print("a.length = " + a.length);
// Массивы примитивов-int[] e, // Ссылка null int[] f = new int[5],
// Примитивы в массиве автоматически инициализируются нулями
printCf. " + Arrays.toString(f)),
int[] g = new int[4];
for(int i = 0. i < g length. i++)
g[i] = i*i. int:: h = { 11, 47, 93 },
// Ошибка компиляции переменная e не инициализирована
//!printC"е length = " + e.length);
printC'f. length = " + f.length),
printC'g length = " + g length),
printC'h length = " + h.length);
e = h,
printC'e.length = " + e length), e = new int[]{ 1.2}, printC'e. length = " + e.length);
}
} /* Output
b [null, null, null, null, null]
a.length = 2
b.length = 5
c. length = 4 d length = 3 a length = 3
f- [0. 0, 0, 0. 0] f length = 5
g.length = 4
h.length = 3 e.length = 3 e length = 2 *///.-
Массив а — неинициализированная локальная переменная, и компилятор не позволяет что-либо делать с этой ссылкой до тех пор, пока она не будет соответствующим образом инициализирована. Массив b инициализируется массивом ссылок на объекты BerylliumSpere, хотя ни один такой объект в массив не заносится. Несмотря на это, мы можем запросить размер массива, потому что b указывает на действительный объект. В этом проявляется некоторый недостаток массивов: поле length сообщает, сколько элементов может быть помещено в массив, то есть размер объекта массива, а не количество хранящихся в нем элементов. Тем не менее при создании объекта массива все ссылки автоматически инициализируются значением null, и, чтобы узнать, связан ли некоторый элемент массива с объектом, достаточно проверить ссылку на равенство null. Аналогично, массивы примитивных типов автоматически инициализируются нулями для числовых типов: (char)o для char и false для boolean.
Массив с демонстрирует создание массива с последующим присваиванием объектов BerylliumSphere всем элементам массива. Массив d демонстрирует синтаксис «агрегатной инициализации», при котором объект массива создается (с ключевым словом new, как массив с) и инициализируется объектами BerylliumSphere, причем все это происходит в одной команде.
Следующую конструкцию инициализации массива можно назвать «динамической агрегатной инициализацией». Агрегатная инициализация, используемая d, должна использоваться в точке определения d, но при втором синтаксисе объект массива может создаваться и использоваться в любой точке. Предположим, методу hide передается массив объектов BerylliumSphere. Его вызов может выглядеть так:
hide(d);
однако массив, передаваемый в аргументе, также можно создать динамически:
hide(new BerylliumSphere[]{ new Beryl 1iumSphere. new BerylliumSphereО });
Во многих ситуациях такой синтаксис оказывается более удобным.
Выражение
a=d;
показывает, как взять ссылку, связанную с одним объектом массива, и присвоить ее другому объекту массива, как это делается с любым другим типом ссылки на объект. В результате and указывают на один объект массива в куче.
Вторая часть ArrayOptions.java показывает, что примитивные массивы работают точно так же, как массивы объектов, за исключением того, что примитивные значения сохраняются в них напрямую.
Возврат массива
Предположим, вы пишете метод, который должен возвращать не отдельное значение, а целый набор значений. В таких языках, как С и С++, это сделать нелегко, потому что возвращается из метода не массив, а только указатель на массив.
При этом возникают проблемы, поскольку сложности с управлением жизненным циклом массива могут привести к утечке памяти.
В Java вы просто возвращаете массив. Вам не нужно беспокоиться о нем — массив будет существовать до тех пор, пока он вам нужен, а когда надобность в нем отпадет, массив будет уничтожен уборщиком мусора. В качестве примера рассмотрим возвращение массива String:
//: arrays/IceCream.java // Возвращение массивов из методов import java.util.*;
public class IceCream {
private static Random rand = new Random(47); static final String[] FLAVORS = {
"Chocolate". "Strawberry", "Vanilla Fudge Swirl". "Mint Chip". "Mocha Almond Fudge". "Rum Raisin". "Praline Cream". "Mud Pie"
}:
public static String[] flavorSet(int n) { if(n > FLAVORS.length)
throw new IllegalArgumentExceptionC'Set too big"); String[] results = new StringCn]; boolean[] picked = new boolean[FLAVORS.length]; for(int i = 0; i < n; i++) { int t; do
t = rand.nextInt(FLAVORS.length); while(picked[t]); results[i] = FLAVORSCt]: picked[t] = true;
}
return results;
}
public static void main(String[] args) { for(int i = 0; i < 7; i++)
System.out.pri ntin(Arrays.toStri ng(f1 avorSet(3)));