Вход/Регистрация
Философия Java3
вернуться

Эккель Брюс

Шрифт:

Мы также видели, что рефлексия открывает перед программистом множество новых возможностей и делает возможным более динамичный стиль программирования. Пожалуй, динамическая природа рефлексии кому-то покажется пугающей. Для тех, кто привык к безопасной статической проверке типов, сама возможность выполнения действий, правильность которых проверяется только на стадии выполнения, а для выдачи информации используются исключения, выглядит шагом в неверном направлении. Некоторые доходят до утверждений, будто сама возможность исключения на стадии выполнения свидетельствует о том, что такого кода лучше избегать. На мой взгляд, чувство безопасности весьма иллюзорно — неожиданности и исключения возможны всегда, даже если программа не содержит блоков try и спецификации исключений. Предпочитаю думать, что существование логически целостной модели выдачи информации об ошибках дает возможность писать динамический код с использованием рефлексии. Конечно, всегда желательно писать код со статической проверкой... когда это возможно. И все же динамический код является одной из важнейших особенностей, отделяющих Java от таких традиционных языков, как С++.

Параметризация

Обычные классы и методы работают с конкретными типами: либо, примитивами, либо с классами. Если ваш код должен работать с разными типами, такая жесткость может создавать проблемы.

Одним из механизмов обеспечения универсальности кода в объектно-ориен-тированных языках является полиморфизм. Например, вы можете написать метод, который получает в аргументе объект базового класса, а затем использует этот метод с любым классом, производным от него. Метод становится чуть более универсальным, а область его применения расширяется. Это относится и к классам — использование базового класса вместо производного обеспечивает дополнительную гибкость. Конечно, наследование возможно только для классов, не являющихся final.

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

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

В этом и состоит концепция параметризации — одного из самых значительных новшеств Java SE5. Параметризованные типы позволяют создавать компоненты (прежде всего, контейнеры), которые могут легко использоваться с разными типами. Если прежде вы еще никогда не встречались с механизмом параметризации в действии, вероятно, параметризованные типы Java покажутся вам довольно удобным дополнением к языку. При создании экземпляра параметризованного типа преобразования типа выполняются автоматически, а правильность типов проверяется на стадии компиляции. С другой стороны, разработчики с опытом использования параметризованных типов в других языках (скажем, в С++) увидят, что в Java они не соответствуют всем ожиданиям. Если использовать готовый параметризованный тип относительно несложно, при попытке написать собственный тип вас ждут сюрпризы. В частности, в этой главе я постараюсь объяснить, почему параметризованные типы Java получились именно такими.

Не стоит думать, что параметризованные типы Java бесполезны — во многих случаях они делают код более четким и элегантным. Но, если вы работали на другом языке, в котором они были реализованы более «чисто», вас могут ждать разочарования. В этой главе мы изучим как достоинства, так и недостатки параметризованных типов Java, чтобы вы могли использовать эту новую возможность более эффективно.

Простая параметризация

Одной из важнейших причин для появления параметризации стало создание классов контейнеров (см. главу 11). Контейнер предназначен для хранения объектов, используемых в программе. В принципе это описание подойдет и для массива, но контейнеры обычно обладают большей гибкостью и отличаются по своим характеристикам от простых массивов. Необходимость хранения групп объектов возникает едва ли не в каждой программе, поэтому контейнеры составляют одну из самых часто используемых библиотек классов.

Рассмотрим класс для хранения одного объекта. Конечно, в этом классе можно указать точный тип объекта:

//• generics/Holderl java

class Automobile {}

public class Holderl {

private Automobile a;

public Holderl(Automobile a) { this.a = a; } Automobile get { return a; }

} ///:-

Однако такой «контейнер» получается не слишком универсальным — он не может использоваться только для одного типа. Конечно, было бы неудобно создавать новый класс для каждого типа, который нам встретится в программе.

До выхода Java SE5 можно было бы хранить в классе Object:

II: generics/Holder2.java

public class Holder2 { private Object a;

public Holder2(0bject a) { this a = a; } public void set(Object a) { this.a = a; }

public Object get О { return a; } public static void main(String[] args) {

Holder2 h2 = new Holder2(new AutomobileO); Automobile a = (Automobile)h2 get; h2.set("He Automobile"); String s = (String)h2:get;

h2.set(l); // Автоматически упаковывается в Integer Integer x = (Integer)h2.get,

}

} ///:-

Теперь класс Holder2 может хранить все, что угодно, — в приведенном примере один объект Holder2 используется для хранения трех разных типов данных.

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

  • Читать дальше
  • 1
  • ...
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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