Философия Java3
вернуться

Эккель Брюс

Шрифт:

И массивы, и контейнеры защищены от возможных злоупотреблений. При выходе за границу массива или контейнера происходит исключение RuntimeException, свидетельствующее об ошибке программиста.

До появления параметризации другим контейнерным классам приходилось работать с объектами так, как если бы они не имели определенного типа. Иначе говоря, объекты рассматривались как принадлежащие к типу Object, корневому для всей иерархии классов в Java. Массивы удобнее «старых» контейнеров тем, что массив создается для хранения конкретного типа. Проверка типов на стадии компиляции не позволит использовать неверный тип или неверно интерпретировать извлекаемый тип. Конечно, Java так или иначе запретит отправить неподходящее сообщение объекту на стадии компиляции или выполнения, так что ни один из способов не является более рискованным по сравнению с другим. Просто будет удобнее, если компилятор укажет на существующую проблему, и снижается вероятность того, что пользователь программы получит неожиданное исключение.

Массив может содержать примитивные типы, а «старые» контейнеры — нет. С другой стороны, параметризованные контейнеры могут проверять тип хранимых объектов, а благодаря автоматической упаковке они работают так, как если бы поддерживали хранение примитивов, поскольку преобразование выполняется автоматически. В следующем примере массивы сравниваются с параметризованными контейнерами:

//• arrays/Contai nerComparison.java

import java.util *;

import static net mindview.util Print *;

class BerylliumSphere {

private static long counter,

private final long id = counter++;

public String toStringO { return "Sphere " + id; }

}

public class ContainerComparison {

public static void main(String[] args) {

BerylliumSphere[] spheres = new Beryl 1iumSphere[10]; for(int i =0; i <5; i++)

spheres[i] = new Beryl 1iumSphere, pri nt(Arrays.toStri ng(spheres)); print(spheres[4]);

List<BerylliumSphere> sphereList =

new ArrayLi st<Bery11i umSphere>, for(int i = 0; i < 5, i++)

sphereList add(new BerylliumSphereO); print(sphereList); print(sphereList.get(4));

int[] integers = { 0, 1. 2, 3. 4, 5 }; pri nt(Arrays.toString(integers)), print(integers[4]);

List<Integer> intList = new ArrayList<Integer>(

Arrays asl_ist(0, 1. 2, 3. 4, 5)); intList.add(97); print(intList);

print(intList get(4)): продолжение &

}

} /* Output

[Sphere 0. Sphere 1. Sphere 2. Sphere 3, Sphere 4, null, null, null. null, null] Sphere 4

[Sphere 5. Sphere 6. Sphere 7. Sphere 8. Sphere 9] Sphere 9

[0. 1, 2. 3. 4. 5] 4

[0. 1. 2. 3. 4. 5. 97] 4

*/// ~

Оба способа хранения объектов обеспечивают проверку типов, а единственное очевидное различие заключается в том, что массивы используют для обращения к элементам конструкцию [], a List — методы вроде add или get. Разработчики языка намеренно сделали массивы и ArrayList настолько похожими, чтобы программисту было концептуально проще переключаться между ними. Но, как было показано в главе И, контейнеры обладают более широкими возможностями, чем массивы.

С появлением механизма автоматической упаковки контейнеры по удобству работы с примитивами почти не уступают массивам. Единственным реальным преимуществом массивов остается их эффективность. Впрочем, при решении более общих проблем может оказаться, что возможности массивов слишком ограничены, и тогда приходится пользоваться контейнерными классами.

Массив как объект

С каким бы типом массива вы ни работали, идентификатор массива в действительности представляет собой ссылку на объект, созданный в динамической памяти. Этот объект содержит ссылки на другие объекты и создается либо неявно (в синтаксисе инициализации массива), либо явно конструкцией new. Одной из частей объекта массива (а по сути, единственным доступным полем) является доступная только для чтения переменная length, которая указывает, сколько элементов может храниться в объекте массива. Весь доступ к объекту массива ограничивается синтаксисом [ ].

Следующий пример демонстрирует различные способы инициализации массивов и присваивания ссылок на массивы. Он также наглядно показывает, что массивы объектов и массивы примитивных типов практически идентичны. Единственное различие заключается в том, что массивы объектов содержат ссылки, а массивы примитивов содержат сами примитивные значения.

//• arrays/ArrayOptions.java

// Инициализация и повторное присваивание массивов

import java util.*,

import static net mindview.util Print *;

public class ArrayOptions {

public static void main(String[] args) { // Массивы объектов.

BerylliumSphere[] a. // Локальная неинициализированная переменная BerylliumSphere[] b = new Beryl 11umSphere[5];

// Ссылки в массиве автоматически инициализируются null printC'b. " + Arrays toString(b)). BerylliumSphere[] с = new Beryl 1iumSphere[4], for(int i =0, i < с length, i++)

if(c[i] == null) // Проверка ссылки на действительность [i] = new Beryl 1iumSphere, // Агрегатная инициализация. BerylliumSphere[] d = { new Beryl 1iumSphere.

  • Читать дальше
  • 1
  • ...
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • ...

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • help@private-bookers.win

Подпишитесь на рассылку: