Философия Java3
Шрифт:
}
} /* 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, хотя ни один такой объект в массив не заносится. Несмотря на это, мы можем запросить размер массива,
Массив с демонстрирует создание массива с последующим присваиванием объектов 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)));
}
} /* Output;
[Rum Raisin. Mint Chip. Mocha Almond Fudge] [Chocolate, Strawberry. Mocha Almond Fudge] [Strawberry. Mint Chip, Mocha Almond Fudge] [Rum Raisin. Vanilla Fudge Swirl. Mud Pie] [Vanilla Fudge Swirl. Chocolate, Mocha Almond Fudge] [Praline Cream. Strawberry. Mocha Almond Fudge] [Mocha Almond Fudge, Strawberry. Mint Chip] *///:-
Метод flavorSet
Из выходных данных видно, что метод flavorSet действительно выбирает случайное подмножество элементов при каждом вызове.
Многомерные массивы
Создание многомерных массивов в Java не вызывает особых сложностей. Для многомерных массивов примитивных типов каждый вектор заключается в фигурные скобки:
// arrays/MultidimensionalPrimitiveArray.java // Создание многомерных массивов import java.util.*.
public class MultidimensionalPrimitiveArray { public static void main(String[] args) { int[][] a = {
{ 1. 2. 3. }. { 4, 5, 6, }.
}:
System out println(Arrays.deepToString(a));
}
} /* Output: [[1. 2, 3]. [4, 5. 6]] *///:-
Каждая вложенная пара фигурных скобок описывает новую размерность массива.
В этом примере используется метод Java SE5 Arrays.deepToString. Как видно из выходных данных, он преобразует многомерные массивы в String.
Массив также может создаваться ключевым словом new. Пример создания трехмерного массива выражением new:
//: arrays/ThreeDWithNew.java import java.util.*;
public class ThreeDWithNew {
public static void main(String[] args) {
// Трехмерный массив фиксированной длины:
int[][][] а = new int[2][2][4]:
System.out.pri ntln(Arrays.deepToStri ng(a)):
}
} /* Output:
[[[0. 0. 0, 0]. [0. 0. 0, 0]]. [[0, 0, 0. 0]. [0. 0. 0, 0]]] *///•-
Как видите, если массиву примитивйых типов не заданы явные значения, он автоматически инициализируется значениями по умолчанию. Массивы объектов инициализируются ссылками null.