Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Создание и уничтожение объектов



           

1. Рассмотрите возможность замены конструкторов статическими методами генерации…………………………………………………………......5

2. Свойство синглтона обеспечивайте закрытым конструктором……………9

3. Отсутствие экземпляров обеспечивает закрытый конструктор………….11

4. Не создавайте дублирующих объектов……………………………………...12

5. Уничтожайте утаревшие ссылки ( на объекты)……………………………..16

6. Остерегайтесь методов finalize………………………………………………..19

 

Методы, общие для всех объектов

 

7. Переопределяя метод euals, соблюдайте общие соглашения………….24

8. Переопределяя метод equals? Всегда переопределяйте hashCode…...................................................................................................35

9. Всегда переопределяйте метод toString……………………………………..40

10. Соблюдайте осторожность при переопределении метода clone………..43

11. Подумайте над реализацией интерфейса Comparable…………………..........................................................................51

 

Классы и интерфейсы

 

12. Сводите к минимуму доступность классов и членов………………………57

13. Предпочтитайте постоянство………………………………………………….61

14. Предпочитайте компановку наследованию…………………………………69

15. Проектируйте и документируйте наследование либо запрещайте его…………………………………………………………………………………..75

16. Предпочитайте интерфейсы абстрактным классам……………………….80

17. Используйте интерфейсы только для определения типов……………….85

18. Предпочитайте статистические классы-члены нестатическим………….87

 

Замена конструкций на языке C

19. Заменяйте структуру классом………...……………………………………….92

20. Заменяйте объединение иерархией классов……………………………….94

21. Заменяйте конструкцию enum классом………………………………………98

22. Указатель на функцию заменяйте классом и интерфейсом…………….109

 

Методы

23. Проверяйте достоверность параметров……………………………………112

24. При необходимости создавайте резервные копии……………………….114

25. Тщательно проектируйте сигнатуру…………………………………………118

26. Перезагружая методы, соблюдайте осторожность……………………….120

27. Возвращайте массив нулевой длины, а не null……………………………125

28. Для всех открытых элементов АРI пишите dос-комментарии………….127

 

 

7. Общие вопросы программирования

29. Сводите к минимуму область видимости локальных переменных…….132

30. Изучите библиотеки и пользуйтесь ими…………………………………….135

31. Если требуются точные ответы, избегайте использования типов float и doubIe……………………………………………………………………………..139

32. Не используйте строку там, где более уместен иной тип……………….141

33. При конкатенации строк опасайтесь потери производительности…………144

34. Для ссылки на объект используйте его интерфейс…………………………...145

35. Предпочитайте интерфейс отражению класса………………………………...147

36. Соблюдайте осторожность при использовании машинно-зависимых методов……………………………………………………………………………….150

37. Соблюдайте осторожность при оптимизации………………………………….151

38. выборе имен придерживайтесь общепринятых соглашений………………..154

 

Исключения

39. Используйте исключения лишь в исключительных ситуациях……………158

40. Применяйте обрабатываемые исключения для восстановления, для программных ошибок используйте исключения времени выполнения…………………………………………………………………………161

41. Избегайте ненужных обрабатываемых исключений…………………………163

42. Предпочитайте стандартные исключения……………………………………..165

43. Инициируйте исключения, соответствующие абстракции…………………..167

44. Для каждого метода документируйте все инициируемые исключения…………………………………………………………………………..170

45. В описание исключения добавляйте информацию о сбое…………………..171

46. Добивайтесь атомарности методов по отношению к сбоям…………………173

47. Не игнорируйте исключений………………………………………………………175

 

Потоки

48. Синхронизируйте доступ потоков к совместно используемым изменяемым данным………………………………………………………………………………..177

49. Избегайте избыточной синхронизации………………………………………….183

50. Никогда не вызывайте метод wait вне цикла…………………………………..188

51. Не попадайте в зависимость от планировщика потоков……………………..191

52. При работе с потоками документируйте уровень безопасности……………194

53. Избегайте группировки потоков…………………………………………………..197

 

Сериализация

 

54. Соблюдайте осторожность при реализации интерфейса SerializabIe…………………………………………………………………………...199

55. Рассмотрите возможность использования специализированной сериализованной формы…………………………………………………………..204

56. Метод readObject должен создаваться с защитой…………………………….210

57. При необходимости создавайте метод readResolve………………………….217

 

Литература

 

Предисловие

Если бы сослуживец сказал вам: "Моя супруга сегодня вечером готовит дома нечто необычное. Придешь?" (Spouse of me this night today manufactures the unusual meal in а home. You will join?), вам в голову, вероятно, пришли бы сразу три мысли: вас уже пригласили на обед; английский язык не является родным для вашего сослуживца; ну и прежде всего это слишком большое беспокойство.

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

Практически так же обстоит дело с языком программирования. Вы должны понимать суть языка: является ли он алгоритмическим, функциональным, объектно-ориентированным. Вам нужно знать словарь языка: какие структуры данных, опера­ции и возможности' предоставляют стандартные библиотеки. Кроме того, вам необхо­димо ознакомиться с общепринятыми и эффективными способами структурирования Кода. В книгах, посвященных языкам программирования, часто освещаются лишь первые два вопроса, приемы работы с языком, если и обсуждаются, то лишь кратко. Возможно, это происходит потому, что о первых двух вещах писать несколько проще. Грамматика и словарь - это свойства самого языка, тогда как способ его применения характеризует группу людей, пользующихся этим языком.

Например, язык программирования Java - объектно-ориентированный язык с единичным наследованием, обеспечивающим для каждого метода императивный (ориентированный на действия) стиль программирования. Его библиотеки ориенти­рованы на поддержку графических дисплеев, на работу с сетью, на распределенные вычисления и безопасность. Но как наилучшим образом использовать этот язык на практике?

Есть и другой аспект. Программы, в отличие от произнесенных фраз и большин­ства изданных книг и журналов, имеют возможность меняться со временем. Недоста­точно создать программный код, который эффективно работает и без труда может быть понят другими людьми. Нужно еще организовать этот код таким образом, чтобы его можно было легко модифицировать для не которой задачи А существует десяток вариантов написания программного кода. Из этих десяти семь оказываются неуклю­жими, неэффективными или запутывающими читателя. Какой же из оставшихся трех вариантов будет представлять собой программный код, который потребуется в следую­щем году для новой версии программы, ,решающей задачу А'?

Существует много книг, по которым можно изучать грамматику языка програм­мирования Jаvа, в том числе книги "The Java Prograттiпg Laпguage" авторов Arnold, Gosling и Holmes [ArnoldOO] и "The Java Laпguage Spec if icatioп" авторов Gosling, Jоу, Bracha и вашего покорного слуги [JLS]. Немало книг посвящено библиотекам и при­кладным интерфейсам, связанным с Jаvа.

Эта книга посвящена третьей теме: общепринятым и эффективным приемам работы с языком Jаvа. На протяжении нескольких лет Джошуа Блох (Joshua Blосk) трудился в компании Sun Microsystems, работая с языком программирования Jаvа, занимаясь расширением и реализацией программного кода. Он изучил большое коли­чество программ, написанных многими людьми, в том числе и мною. 8 настоящей книге он дает дельные советы о том, каким образом структурировать код, чтобы он ра­ботал хорошо, чтобы его могли понять другие люди, чтобы последующие модификации и усовершенствования доставляли меньше головной боли и чтобы ваши программы были приятными, элегантными и красивыми.

Гай А. Стuл-младшuй (Сиу L. Steele Jr.) Берлингтон, шт. Массачусетс Апрель 2001

 

        Предисловие автора

 

 

в 1996г. я направился на запад, в компанию JavaSoft, как она тогда называлась, поскольку было очевидно, что именно там происходят главные события. На протяже­нии пяти лет я работал архитектором библиотек для платформы Java. Я занимался проектированием, разработкой и обслуживанием этих библиотек, а также давал консультации по многим другим библиотекам. Контроль над библиотеками в ходе становления платформы языка Java - такая возможность предоставляется раз в жизни. Не будет преувеличением сказать, что я имел честь трудиться бок о бок с великими разработчиками нашего времени. Я многое узнал о языке программирова­ния Java: что в нем работает, а что нет, как пользоваться языком и его библиотеками для получения наилучшего результата.

Эта книга является попыткой поделиться с вами моим опытом, чтобы вы смогли повторить мои успехи и избежать моих неудач. Оформление книги я позаимствовал из руководства Скотта Мейерса (Scott Meyers) "Effective С++" [Meyers98]; оно состоит из пятидесяти статей, каждая из которых посвящена одному конкретному правилу, направленному на улучшение программ и проектов. Я нашел такое оформле­ние необычайно эффективным, и надеюсь, вы тоже его оцените.

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

Эта книга предназначена не только для тех, кто занимается разработкой повтор­но используемых компонентов, тем не менее она неизбежно отражает мой опыт в написании таковых, накопленный за последние два десятилетия. Я привык думать в терминах прикладных интерфейсов (API) и предлагаю вам делать то же. Даже если вы не занимаетесь разработкой повторно используемых компонентов, примене­ние этих терминов поможет вам повысить качество ваших программ. Более того, нередко случается писать многократно используемые компоненты, не подозревая об этом: вы создали нечто полезное, поделились своим результатом с приятелем, и вскоре у вас будет уже с полдюжины пользователей. С этого момента вы лишае­тесь возможности свободно менять этот АР! и получаете благодарности за все те усилия, которые потратили на его разработку, когда писали программу в первый раз.

Мое особое внимание к разработке АР! может показаться несколько противо­естественным для ярых приверженцев новых облегченных методик создания програм­много обеспечения, таких как "Экстремальное программирование" [Beck99]. В этих методиках особое значение придается написанию самой простой программы, какая только сможет работать. Если вы пользуетесь одной из этих методик, то обнаружите, что внимание к АРI сослужит вам добрую службу в процессе последующей перестройки программы (refactoring). Основной задачей перестроения является усовер­шенствование структуры системы, а также исключение дублирующего программного кода. Этой цели невозможно достичь, если у компонентов системы нет хорошо спроектированного API.

Ни один язык не идеален, но некоторые - великолепны. Я обнаружил, что язык программирования Java и его библиотеки в огромной степени способствуют повыше­нию качества и производительности труда, а также доставляют радость при работе с ними. Надеюсь, эта книга отражает мой энтузиазм и способна сделать вашу работу с языком Java более Эффективной и приятной.

Джошуа Блох

Купертино, шт. Калифорния

Апрель 2001

 

                       Глава 1

Введение

Эта книга писалась с той целью, чтобы помочь вам наиболее эффективно ис­пользовать язык программирования Jаvа ТМ и его основные библиотеки jаvа.lang, java.util и java.io. В книге рассматриваются и другие библиотеки, но мы не касаем­ся графического интерфейса пользователя и специализированных API.

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

Большинство статей сопровождается примерами программ. Главной особенностью этой книги является наличие в ней примеров программного кода, иллюстрирующих многие шаблоны (design pattern) и идиомы. Некоторые из них, такие как Singleton (статья 2), известны давно, другие появились недавно, например Finalizer Guardian (статья б) и Defensive readResolve (статья 57). Где это необходимо, шаблоны и идио­мы имеют ссылки на основные работы в данной области [Саmmа95].

Многие статьи содержат при меры программ, иллюстрирующие приемы, которых следует избегать. Подобные примеры, иногда называемые "антишаблонами", четко обозначены комментарием "// никогда не делайте так!" В каждом таком случае в статье дается объяснение, почему пример плох, и предлагается альтернатива.

Эта книга не предназначена для начинающих: предполагается, что вы уже хорошо владеете языком программирования Java. В противном случае обратитесь к одному из множества прекрасных изданий для начинающих [ArnoldOO, CampioneOO]. Книга построена так, чтобы быть доступной для любого, кто работает с этим языком, тем не менее она дает пищу для размышлений даже опытным программистам.

 

1

 

В основе большинства правил этой книги лежит несколько фундаментальных принципов. Ясность и простота имеют первостепенное значение. Функционирование модуля не должно вызывать удивление у него пользователя. Модули Должны быть на­столько компактны, насколько это возможно, но не более того. (В этой книге термин "модуль" относится к любому программному компоненту, который используется много раз: от отдельного метода до сложной системы, состоящей из нескольких пакетов.) Программный код следует использовать повторно, а не копировать. Взаимозависи­мость между модулями должна быть сведена к минимуму. Ошибку нужно выявлять как можно раньше, в идеале - уже на стадии компиляции.

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

Большая часть этой книги посвящена отнюдь не производительности программ.

Речь идет о написании понятных, прав ильных, полезных, надежных, гибких программ, которые удобно сопровождать. Если вы сможете сделать это, то добиться необхо­димой производительности будет несложно (статья 37). В некоторых статьях об­суждаются вопросы производительности, в ряде случаев приводятся показатели производительности. Эти данные, предваряемые выражением "на моей машине", следует рассматривать как приблизительные.

Для справки, моя машина - это старый компьютер домашней сборки с процес­сором 400 МГц Pentium® II и 128 Мбайт оперативной памяти под управлением Мiсrosоft Windows NT® 4.0, на котором установлен Java 2 Standard Edition Software Development Kit (SDK) компании Sun. В состав этого SDK входит Java HotSpot тм Client УМ компании Sun - финальная реализация виртуальной машины Java, пред­назначенной для клиентов.

При обсуждении особенностей языка программирования Jаvа и его библиотек иногда необходимо ссылаться на конкрет­ные версии для краткости в этой книге используются "рабочие", а не официальные номера версий. В таблице 1.1 показано со­ответствие между названиями версий и их рабочими номерами.

В некоторых статьях обсуждаются возможности, появившиеся в версии 1.4, однако в примерах программ, за редким 'исключением, я воздерживался от того, чтобы пользоваться ими. Эти примеры были проверены в версии 1.3. Большинство из них, если не все, без всякой переделки должны работать также с версией 1.2.

 

Официальное название версии Рабочий номер версии
JDK 1.1.x / JRE 1.1.x 1.1
Java 2 Platform, Standard Edition, v1.2 1.2
Java 2 Platform, Standard Edition, v1.3 1.3
Java 2 Platform, Standard Edition, v1.4 1.4

 

2

 

 

Примеры по возможности являются полными, однако предпочтение отдается не завершенности, а удобству чтения. В примерах широко используются классы пакеТ08 java.util и java. 10. Чтобы скомпилировать пример, вам потребуется добавить один или оба оператора import:

Import java.ut11.*;

Import java.io.*;

В примерах опущены детали. Полные версии всех примеров содержатся на web-сайте этой книги (http://java.sun.com/docs/books/effective). При желании любой из них можно скомпилировать и запустить.

Технические термины в этой книге большей частью используются в том виде, как они определены в "The J а v а Laпguage Speci f icatioп, Secoпd Editioп" [JLS]. Однако некоторые термины заслуживают отдельного упоминания. Язык Java поддерживает четыре группы типов: интерфейсы (interface), классы (class), массивы (аrrау) и простые типы (primitive). Первые три группы называются ссылочными типами (reference type). Экземпляры классов и массивов '- это объекты, значения простых типов таковыми не являются. К членам класса (members) относятся его поля (fields), методы (methods), классы-члены (member classes) и интерфейсы-члены (mernber interfaces). Сигнатура метода (signature) состоит из его названия и типов, которые имеют его формальные параметры. Т ил значения, возвращаемого методом, в сигнатуру не входит.

Некоторые термины в этой книге используются в ином значении, чем в "The J а v а .

Laпguage Speci/icatioп". Так, "наследование" (inheritance) применяется как синоним "образования подклассов" (subclassing). Вместо использования для интерфейсов тер­мина "наследование" в книге констатируется, что некий класс реализует (implement) интерфейс или что один интерфейс является расширением другого (extend) для описания' уровня доступа, который применяется, когда ничего больше не указано, в книге используется описательный термин "доступ только в пределах пакета" (package-private) вместо формально правильного термина "доступ по умолчанию" (default access) [JLS, 6.6.1].

      В этой книге встречается несколько технических терминов, которых нет в "The J а v а La n guage Speci f icatio n ". Термин "внешний АР!" (exported API), или просто АР I ”  относится к классам, интерфейсам, конструкторам, членам и сериализованным формам, с помощью которых программист получает доступ к классу, интерфейсу или пакету. (Термин API , являющийся сокращением от applicatio n programmi n g i n terface - программный интерфейс приложения, используется вместо термина "интерфейс" (interface). Это позволяет избежать путаницы с одноименной конструкцией языка Java.) Программист, который пишет программу, применяющую некий API, называется пользователем (user) указанного API. Класс, в реализации которого используется некий API, называется клиентом (client) этого API.

          

 

3

 

Классы, интерфейсы, конструкторы, члены и сериализованные формы называ­ются элементами АР/ (API element). Внешний API образуется из элементов API, которые доступны за пределами пакета, где этот  API был определен. Указанные элементы может использовать любой клиент, автор АР! берет на себя их поддержку. Неслучайно документацию именно к этим элементам генерирует утилита Javadoc при запуске в режиме по умолчанию. В общих чертах, внешний АР! пакета состоит из открытых (pubIic) и защищенных (protected) членов, а также из конструкторов всех открытых классов и интерфейсов в пакете.

 

 

4

 

 

 

Глава 2


Поделиться:



Последнее изменение этой страницы: 2019-04-11; Просмотров: 213; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.042 с.)
Главная | Случайная страница | Обратная связь