Программирование на языке Java

         

Дейтаграммы



Дейтаграммы

Дейтаграммы, или пакеты протокола UDP (User Datagram Protocol) - это пакеты информации, пересылаемые в сети по принципу "fire-and-forget" (выстрелил и забыл). Если вам надо добиться оптимальной производительности, и вы в состоянии минимизировать затраты на проверку целостности

UDP не предусматривает проверок и подтверждений при передаче информации. При передаче пакета UDP по какому-либо адресу нет никакой гарантии того, что он будет принят, и даже того, что по этому адресу вообще есть кому принимать такие пакеты. Аналогично, когда вы получаете дейтаграмму, у вас нет никаких гарантий, что она не была повреждена в пути или что ее отправитель все еще ждет от вас подтверждения ее получения.

Java реализует дейтаграммы на базе протокола UDP, используя для этого два класса. Объекты класса DatagramPacket представляют собой контейнеры с данными, a DatagramSocket - это механизм, получении объектов DatagramPacket.



Destroy



destroy

Метод destroy вызывается тогда, когда среда (например, браузер Netscape) решает, что апплет нужно полностью удалить из памяти. В этом методе нужно освободить все ресурсы, которые использовал апплет.



Dictionary



Dictionary

Dictionary (словарь) - абстрактный класс, представляющий собой хранилище информации типа "ключ-значение". Ключ - это имя, по которому осуществляется доступ к значению. Имея ключ и значение, вы можете записать их в словарь методом put(key, value). Для получения значения по заданному ключу служит метод get(key). И ключи, и значения можно получить в форме перечисления (объект Enumeration) методами keys и elements. Метод size возвращает количество пар "ключ-значение", записанных в словаре, метод isEmpty возвращает true, если словарь пуст. Для удаления ключа и связанного с ним значения предусмотрен метод remove(key).



Динамическое назначение методов



Динамическое назначение методов

Давайте в качестве примера рассмотрим два класса, у которых имеют простое родство подкласс / суперкласс, причем единственный метод суперкласса замещен в подклассе. class A { void callme() { System.out.println("Inside A's callrne method"); }} class В extends A { void callme() { System.out.println("Inside B's callme method"); }} class Dispatch { public static void main(String args[]) { A a = new B(); a.callme(); } }

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


С:\> Java Dispatch Inside B's calime method Совет
Совет

Программистам Delphi / C++ следует отметить, что все Java по умолчанию являются виртуальными функциями (ключевое слово virtual).

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



Do-while



do-while

Иногда возникает потребность выполнить тело цикла по крайней мере один раз - даже в том случае, когда логическое выражение с самого начала принимает значение false. Для таких случаев в Java используется циклическая конструкция do-while. Ее общая форма записи такова: [ инициализация; ] do { тело; [итерация;] } while ( завершение );

В следующем примере тело цикла выполняется до первой проверки условия завершения. Это позволяет совместить код итерации с условием завершения: class DoWhile { public static void main(String args[]) { int n = 10; do { System.out.println("tick " + n); } while (--n > 0); } }



Double



double

В случае двойной точности, задаваемой с помощью ключевого слова double, для хранения значений используется 64 бита. Все трансцендентные математические функции, такие, как sin, cos, sqrt, возвращают результат типа double. double d; double pi = 3. 14159265358979323846;



DrawArc и fillArc



drawArc и fillArc

Форма методов drawArc и fillArc следующая: drawArc(int x, int у, int width, int height, int startAngle, int sweepAngle)

Эти методы вычерчивают (fillArc заполняет) дугу, ограниченную прямоугольником (x,y,width, height), начинающуюся с угла startAngle и имеющую угловой размер sweepAngle. Ноль градусов соответствует положению часовой стрелки на 3 часа, угол отсчитывается против часовой стрелки (например, 90 градусов соответствуют 12 часам, 180 - 9 часам, и так далее).



DrawLine



drawLine

drawline(int x1, int у1, int х2, int у2)

Этот метод вычерчивает отрезок прямой между точками с координатами (х1,у1) и (х2,у2). Эти линии представляют собой простые прямые толщиной в 1 пиксель. Поддержка разных перьев и разных толщин линий не предусмотрена.



DrawPolyson и fillPolyson



drawPolyson и fillPolyson

Прототипы для этих методов: drawPolygon(int[], int[], int) fillPolygon(int[], int[], int)

Метод drawPolygon рисует контур многоугольника (ломаную линию), задаваемого двумя массивами, содержащими х и у координаты вершин, третий параметр метода - число пар координат. Метод drawPolygon не замыкает автоматически вычерчиваемый контур. Для того, чтобы прямоугольник получился замкнутым, координаты первой и последней точек должны совпадать.



DrawString



drawString

В предыдущих примерах использовался метод drawString(String, x, у). Этот метод выводит строку с использованием текущих шрифта и цвета. Точка с координатами (х,у) соответствует левой границе базовой линии символов, а не левому верхнему углу, как это принято в других методах рисования. Для того, чтобы понять, как при этом располагается описывающий строку прямоугольник, прочтите раздел о метрике шрифта в конце этой главы.



Другие новые особенности A WT



Другие новые особенности A WT

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



EnsureCapacity



ensureCapacity

Если вы после создания объекта StringBuffer захотите зарезервировать в нем место для определенного количества символов, вы можете для установки размера буфера воспользоваться методом ensureCapacity. Это бывает полезно, когда вы заранее знаете, что вам придется добавлять к буферу много небольших строк.



Фабричные методы



Фабричные методы

В классе InetAddress нет доступных пользователю конструкторов. Для создания объектов этого класса нужно воспользоваться одним из его фабричных методов. Фабричные методы - это обычные статические методы, которые возвращают ссылку на объект класса, которому они принадлежат. В данном случае, у класса InetAddress есть три метода, которые можно использовать для создания представителей. Это методы getLocalHost, getByName и

В приведенном ниже примере выводятся адреса и имена локальной машины, локального почтового узла и WWW-узла компании, в которой работает автор. InetAddress Address = InetAddress.getLocalHost(); System.out.println(Address); Address = InetAddress.getByName("mailhost"); System.out.println(Address); InetAddress SW[] = InetAddress.getAllByNarne ("www.starwave.com"); System.out.println(SW);

У класса InetAddress также есть несколько нестатических методов, которые можно использовать с объектами, возвращаемыми только что названными фабричными методами: getHostName() возвращает строку, содержащую символическое имя узла, соответствующее хранящемуся в данном объекте адресу Internet. getAddress() возвращает байтовый массив из четырех элементов, в котором в порядке, используемом в сети, записан адрес Internet, хранящийся в данном объекте. toString() возвращает строку, в которой записано имя узла и его адрес.



Final



final

Все методы и переменные объектов могут быть замещены по умолчанию. Если же вы хотите объявить, что подклассы не имеют права замещать какие-либо переменные и методы вашего класса, вам нужно объявить их как final (в Delphi / C++ не писать слово virtual). final int FILE_NEW = 1;

По общепринятому соглашению при выборе имен переменных типа final - используются только символы верхнего регистра (т.е. используются как аналог препроцерных констант C++). Использование final-методов порой приводит к выигрышу в скорости выполнения кода - поскольку они не могут быть замещены, транслятору ничто не мешает заменять их вызовы встроенным (in-line) кодом (байт-код копируется непосредственно в код вызывающего метода).



Finalize



finalize

В Java существует возможность объявлять методы с именем finalize. Методы finalize аналогичны деструкторам в C++ (ключевой знак ~) и Delphi (ключевое слово destructor). Исполняющая среда Java будет вызывать его каждый раз, когда сборщик мусора соберется уничтожить объект этого класса.



Finally



finally

Иногда требуется гарантировать, что определенный участок кода будет выпол-няться независимо от того, какие исключения были возбуждены и пере-хвачены. Для создания такого участка кода используется ключевое слово finally. Даже в тех случаях, когда в методе нет соответствующего воз-бужденному исключению раздела catch, блок finally будет выполнен до того, как управление перейдет к операторам, следующим за разделом try. У каждого раздела try должен быть по крайней мере или один раз-дел catch или блок finally. Блок finally очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для времен-ного использования в начале выполнения метода. Ниже приведен пример класса с двумя методами, завершение которых происходит по разным причинам, но в обоих перед выходом выполняется код раздела finally. class FinallyDemo { static void procA() { try { System.out.println("inside procA"); throw new RuntimeException("demo"); } finally { System.out.println("procA's finally"); } } static void procB() { try { System.out.println("inside procB"); return; } finally { System.out.println("procB's finally"); } } public static void main(String args[]) { try { procA(); } catch (Exception e) {} procB(); } }

В этом примере в методе procA из-за возбуждения исключения про-исходит преждевременный выход из блока try, но по пути вы-полняется раздел finally. Другой метод procB завершает работу выпол-нением стоящего в try-блоке оператора return, но и при этом перед выходом из метода выполняется программный код блока finally. Ниже приведен результат, полученный при выполнении этой программы. С:\> java FinallyDemo inside procA procA's finally inside procB procB's finally



Float



float

В переменных с обычной, или одинарной точностью, объявляемых с помощью ключевого слова float, для хранения вещественного значения используется 32 бита. float f; float f2 = 3. 14F; // обратите внимание на F, //т.к. по умолчанию все литералы double



FlowLayout



FlowLayout

Класс FlowLayout реализует простой стиль размещения, при котором компоненты располагаются, начиная с левого верхнего угла, слева направо и сверху вниз. Если в данную строку не помещается очередной компонент, он располагается в левой позиции новой строки. Справа, слева, сверху и снизу компоненты отделяются друг от друга небольшими промежутками. Ширину этого промежутка можно задать в конструкторе FlowLayout. Каждая строка с компонентами выравнивается по левому или правому краю, либо центрируется в зависимости от того, какая из констант LEFT, RIGHT или CENTER была передана конструктору. Режим выравнивания по умолчанию - CENTER, используемая по умолчанию ширина промежутка - 5 пикселей.

Ниже приведен пример, в котором в Panel включается несколько компонентов Label. Объект Panel использует FlowLayout с выравниванием RIGHT. /* <applet code = "FlowLayoutDemo" width=200 height=100> </applet> */ import java.awt.*; import java.applet.*; import java.util.*; public class FlowLayoutDemo extends Applet { public void init() { setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 3)); int width = Integer.parseInt(getParameter("width")); int height = Integer.parseInt(getParameter("height")); String val = "Data is not information " + "is not knowledge is not wisdom."; StringTokenizer st = new StringTokenizer(val); while (st.hasMoreTokens()) { add(new Button(st.nextToken())); } } }

Необходимо вызвать пример для двух различных размеров - FlowLayoutDemo1.html, FlowLayoutDemo2.html для того, чтобы проиллюстрировать, как объекты Label перетекают из строки в строку, и при этом строки выравниваются по правому краю (или Вы можете изменять размеры окнa appletViewer).



For



for

В этом операторе предусмотрены места для всех четырех частей цикла. Ниже приведена общая форма оператора записи for. for ( инициализация; завершение; итерация ) тело;

Любой цикл, записанный с помощью оператора for, можно записать в виде цикла while, и наоборот. Если начальные условия таковы, что при входе в цикл условие завершения не выполнено, то операторы тела и итерации не выполняются ни одного раза. В каноническая форме цикла for происходит увеличение целого значения счетчика с минимального значения до определенного предела. class ForDemo { public static void main(String args[]) { for (int i = 1; i

Следующий пример - вариант программы, ведущей обратный отсчет. class ForTick { public static void main(String args[]) { for (int n = 10; n > 0; n--) System.out.println("tick " + n); } }

Обратите внимание - переменные можно объявлять внутри раздела инициализации оператора for. Переменная, объявленная внутри оператора for, действует в пределах этого оператора.

А вот - новая версия примера с временами года, в которой используется оператор for. class Months { static String months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static int monthdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static String spring = "spring"; static String summer = "summer"; static String autumn = "autumn"; static String winter = "winter"; static String seasons[] = { winter, winter, spring, spring, spring, summer, summer, summer, autumn, autumn, autumn, winter }; public static void main(String args[]) { for (int month = 0; month < 12; month++) { System.out.println(months[month] + " is a " + seasons[month] + " month with " + monthdays[month] + " days."); } } }

При выполнении эта программа выводит следующие строки: С:\> Java Months January is a winter month with 31 days. February is a winter month with 28 days. March is a spring month with 31 days. April is a spring month with 30 days. May is a spring month with 31 days. June is a summer month with 30 days. July is a summer month with 31 days. August is a summer month with 31 days. September is a autumn month with 30 days. October is a autumn month with 31 days. November is a autumn month with 30 days. December a winter month with 31 days.



Frame



Frame

Frame - это как раз то, что обычно и считают окном на рабочей поверхности экрана. У объекта Frame есть строка с заголовком, управляющие элементы для изменения размера и линейка меню. Для того, чтобы вывести/спрятать изображение объекта Frame, нужно использовать методы show и hide. Ниже приведен пример апплета, который показывает объект Frame с содержащимся в нем компонентом TextArea. /* <applet code = "FrameDemo" width=200 height=200> </applet> */ import java.awt.*; import java.applet.*; public class FrameDemo extends Applet { public void init() { int width = Integer.parseInt(getParameter("width")); int height = Integer.parseInt(getParameter("height")); String val = "There are two ways of constructing " + "a software design.\n" + "One way is to make it so simple\n" + "that there are obviously no deficiencies.\n" + "And the other way is to make it so complicated" + "that there are no obvious deficiencies.\n\n" + "C.A.R. Hoare\n\n"; TextArea text = new TextArea(val, 80, 40); Frame f = new Frame("Demo Frame"); f.setSize(width, height); f.add("Center", text); f.show(); } }



Программирование на языке Java



get и set

Класс Date включает в себя набор методов для получения и установки отдельных атрибутов, хранящихся в объекте. Каждая из функций семейства get - getYear, getMonth, getDate, getDay, getHours, getMi-nutes и getSeconds - возвращает целое значение. Каждой из функций семейства set - setYear, setMonth, setDate, setHours, setMinutes и setSeconds - в качестве параметра передается целое значение. Вы также можете получить представление объекта Date в виде значения типа long с помощью метода getTime. Возвращаемое этим методом значение представляет собой число миллисекунд, прошедших после 1 января 1970 года.



Программирование на языке Java



getAscent, getDescent, getHeight

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



Программирование на языке Java



getDocumentBase и getCodeBase

Возможно, Вы будете писать апплеты, которым понадобится явно загружать данные и текст. Java позволяет апплету загружать данные из каталога, в котором располагается HTML-документ, запустивший апплет (база документа - getDocumentBase), и из каталога, из которого был загружен class-файл с кодом апплета (база кода - getCodeBase).



Программирование на языке Java



getFamily и getName

Метод getFamily возвращает строку с именем семейства шрифтов. С помощью метода getName можно получить логическое имя шрифта.



Программирование на языке Java



getMaxAscent и getMaxDescent

Эти методы служат для получения максимальных подъема и снижения всех символов в шрифте.



Программирование на языке Java



getSize

Этот метод возвращает целое число, представляющее собой размер шрифта в пунктах.



Программирование на языке Java



getStyle

Этот метод возвращает целое число, соответствующее стилю шрифта. Полученный результат можно побитово сравнить со статическими переменными класса Font: - PLAIN, BOLD и ITALIC.



Введение в язык Java



Глава 3 - Введение в язык Java

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

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



Типы



Глава 4 - Типы

В этой главе вы познакомитесь со всеми основными типами языка Java и увидите, как надо объявлять переменные, присваивать им значения и использовать выражения со смешанными типами. В данной главе мы и обсудим простые типы языка Java, оставив сложные типы до главы 7.



Операторы



Глава 5 - Операторы

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

В Java имеется 44 встроенных оператора. Их можно разбить на 4 класса - арифметические, битовые, операторы сравнения и логические.



Управление выполнением программы



Глава 6 - Управление выполнением программы

Управление в Java почти идентично средствам, используемым в С и C++.



Классы



Глава 7 - Классы

Базовым элементом объектно-ориентированного программирования в языке Java является класс. В этой главе Вы научитесь создавать и расширять свои собственные классы, работать с экземплярами этих классов и начнете использовать мощь объектно-ориентированного подхода. Напомним, что классы в Java не обязательно должны содержать метод main. Единственное назначение этого метода - указать интерпретатору Java, откуда надо начинать выполнение программы. Для того, чтобы создать класс, достаточно иметь исходный файл, в котором будет присутствовать ключевое слово class, и вслед за ним - допустимый идентификатор и пара фигурных скобок для его тела. class Point { } Замечание
Замечание

Имя исходного файла Java должно соответствовать имени хранящегося в нем класса. Регистр букв важен и в имени класса, и в имени файла.

Как вы помните из главы 2, класс - это шаблон для создания объекта. Класс определяет структуру объекта и его методы, образующие функциональный интерфейс. В процессе выполнения Java-программы система использует определения классов для создания представителей классов. Представители являются реальными объектами. Термины , и взаимозаменяемы. Ниже приведена общая форма определения класса. class имя_класса extends имя_суперкласса { type переменная1_объекта: type переменная2_объекта: type переменнаяN_объекта: type имяметода1(список_параметров) { тело метода; } type имяметода2(список_параметров) { тело метода; } type имя методаМ(список_параметров) { тело метода; } }

Ключевое слово extends указывает на то, что - это подкласс класса . Во главе классовой иерархии Java стоит единственный ее встроенный класс - Object. Если вы хотите создать подкласс непосредственно этого класса, ключевое слово extends и следующее за ним имя суперкласса можно опустить - транслятор включит их в ваше определение автоматически. Примером может служить класс Point, приведенный ранее.



Пакеты и интерфейсы



Глава 8 - Пакеты и интерфейсы

Пакет (package) - это некий контейнер, который используется для того, чтобы изолировать имена классов. Например, вы можете создать класс List, заключить его в пакет и не думать после этого о возможных конфликтах, которые могли бы возникнуть если бы кто-нибудь еще создал класс с именем List.

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



Работа со строками



Глава 9 - Работа со строками

В этой главе обсуждаются средства языка Java для работы со строками. В язы-ках С и C++ отсутствует встроенная поддержка такого объекта, как строка. В них при необхо-димости передается адрес последовательности байтов, содержимое которых трактуется как символы до тех пор, пока не будет встречен нулевой байт, отмечающий конец строки. В пакет java.lang встроен класс, инкапсулирующий структуру данных, соответ-ствующую строке. Этот класс, называемый String, не что иное, как объ-ектное представление неизменяемого символьного массива. В этом классе есть методы, которые позволяют сравнивать строки, осуществлять в них поиск и извлекать определенные символы и подстроки. Класс StringBuffer используется тогда, когда строку после создания требу-ется изменять.



Обработка исключений



Глава 10 - Обработка исключений

В этой главе обсуждается используемый в Java механизм обработки исключений. Исключение в Java - это объект, который описывает исключительное состояние, воз-никшее в каком-либо участке программного кода. Когда возникает ис-ключительное состояние, создается объект класса Exception. Этот объект пересылается в метод, обрабатывающий данный тип исключительной ситуации. Исключения могут возбуждаться и для того, чтобы сообщить о некоторых нештатных ситуациях.



Легковесные процессы и синхронизация.



Глава 11 - Легковесные процессы и синхронизация.

Параллельное программирование, связанное с использованием легковесных процессов, или подпроцессов (multithreading, light-weight processes) — концептуальная парадигма, в которой вы разделяете свою программу на два или несколько процессов, которые могут исполняться одновременно. Замечание
Замечание

Во многих средах параллельное выполнение заданий представлено в том виде, который в операционных системах называется многозадачностью. Это совсем не то же самое, что параллельное выполнение подпроцессов. В многозадачных операционных системах вы имеете дело с полновесными процессами, в системах с параллельным выполнением подпроцессов отдельные задания называются легковесными процессами (light-weight processes, threads).



Утилиты



Глава 12 - Утилиты

Библиотека классов языка включает в себя набор вспомогательных классов, широко используемых в других встроенных пакетах Java. Эти классы расположены в пакетах java.lang и java.util. Они используются для работы с наборов объектов, взаимодействия с системными функциями низкого уровня, для работы с математическими функциями, генерации случайных чисел и манипуляций с датами и временем.



Сетевые средства



Глава 14 - Сетевые средства

Эта глава посвящена описанию пакета java.net. Java поддерживает протокол TCP/IP, во-первых, расширяя свой интерфейс потоков ввода-вывода, описанного в предыдущей главе, и во вторых, добавляя возможности, необходимые для построения объектов ввода-вывода при работе в сети.



Апплеты



Глава 15 - Апплеты

Апплеты - это маленькие приложения, которые размещаются на серверах Internet, транспортируются клиенту по сети, автоматически устанавливаются и запускаются на месте, как часть документа HTML. Когда апплет прибывает к клиенту, его доступ к ресурсам ограничен.

Ниже приведен исходный код канонической программы HelloWorld, оформленной в виде апплета: import java.awt.*; import java.applet.*; public class HelloWorldApplet extends Applet { public void paint(Graphics g) { g.drawString("Hello World!", 20, 20); } }

Этот апплет начинается двумя строками, которые импортируют все пакеты иерархий java.applet и java.awt. Дальше в нашем примере присутствует метод paint, замещающий одноименный метод класса Applet. При вызове этого метода ему передается аргумент, содержащий ссылку на объект класса Graphics. Последний используется для прорисовки нашего апплета. С помощью метода drawString, вызываемого с этим объектом типа Graphics, в позиции экрана (20,20) выводится строка "Hello World".

Для того, чтобы с помощью браузера запустить этот апплет, нам придется написать несколько строк html-текста. <applet code="HelloWorldApplet" width=200 height=40> </applet>

Вы можете поместить эти строки в отдельный html-файл (HelloWorldApplet.html), либо вставить их в текст этой программы в виде комментария и запустить программу appletviewer с его исходным текстом в качестве аргумента.



Набор абстракций для работы с окнами



Глава 16 - Набор абстракций для работы с окнами

Трудность при создании независимой от платформы библиотеки заключается в том, что ее разработчикам либо приходится требовать, чтобы все приложения на всех платформах вели себя и выглядели одинаково, либо для поддержки, скажем, трех различных разновидностей интерфейса приходится писать в три раза больше кода. Существуют два взгляда на эту проблему. Один подход заключается в том, что упор делается на графику низкого уровня - рисование пикселей, при этом разработчики библиотеки сами заботятся о внешнем виде каждого компонента. При другом подходе создаются абстракции, подходящие для библиотек каждой из операционных систем, и именно "родные" пакеты данной операционной системы служат подъемной силой для архитектурно-нейтральной библиотеки на каждой из платформ. В Java при создании библиотеки Abstraction Window Toolkit (AWT) выбран второй подход.

Классы Graphics и Fonts мы уже обсуждали в главе 15. В главе 18 будут обсуждаться различные возможности работы с изображениями. В данной главе мы пройдемся по базовой архитектуре AWT, касающейся интерфейсных объектов.



Модели обработки событий.



Глава 17 - Модели обработки событий.

Несмотря на существенные изменения механизма обработки событий в AWT, Java1.1 поддерживает обратную совместимость с моделью обработки событий, принятой в Java 1.0. Однако такая совместимость относится к типу "все или ничего" - эти две модели настолько отличаются друг от друга, что их невозможно использовать в одном приложении одновременно.



Работа с изображениями



Глава 18 - Работа с изображениями

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

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



Глобальные переменные



Глобальные переменные

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

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



Программирование на языке Java



Goto

Другая не слишком хорошая конструкция традиционных языков программирования - оператор goto, предназначенный для передачи управления. Всем нам на первых занятиях по программированию говорили, что можно обойтись без этого оператора, ухудшающего структуру программы и делающего ее неудобочитаемой. До того, как в C++ появился механизм работы с исключениями, goto активно использовался для выхода из циклов в исключительных ситуациях.

В Java оператора goto нет. В ней есть зарезервированное ключевое слово goto, но это сделано лишь во избежание возможной путаницы - для того, чтобы удержать программистов от его использования. Зато в Java есть операторы continue и break с меткой, восполняющие отсутствие goto в тех единственных случаях, когда использование последнего было бы оправдано. А мощный хорошо определенный встроенный в Java механизм исключений делает ненужным использование goto во всех остальных ситуациях.



Программирование на языке Java



GridLayout

Класс GridLayout размещает компоненты в простой равномерной сетке. Конструктор этого класса позволяет задавать количество строк и столбцов. Ниже приведен пример, в котором GridLayout используется для создания сетки 4х4, 15 квадратов из 16 заполняются кнопками, помеченными соответствующими индексами. Как вы уже, наверное, поняли, это - панель для игры в "пятнашки". /* <applet code = "GridLayoutDemo" width=200 height=200> </applet> */ import java.awt.*; import java.applet.*; public class GridLayoutDemo extends Applet { static final int n = 4; public void init() { setLayout(new GridLayout(n, n)); setFont(new Font("Helvetica", Font.BOLD, 24)); int width = Integer.parseInt(getParameter("width")); int height = Integer.parseInt(getParameter("height")); for (int i=0;i0) add(new Button(""+k)); } } } }



HashTable



HashTable

HashTable - это подкласс Dictionary, являющийся конкретной реализацией словаря. Представителя класса HashTable можно использовать для хранения произвольных объектов, причем для индексации в этой коллекции также годятся любые объекты. Наиболее часто HashTable используется для хранения значений объектов, ключами которых служат строки (то есть объекты типа String). В очередном нашем примере в HashTable хранится информация об этой книге. import java.util.Dictionary; import java.util.Hashtable; class HTDemo { public static void main(String args[]) { Hashtable ht = new Hashtable(); ht.put("title", "The Java Handbook"); ht.put("author", "Patrick Naugnton"); ht.put("email", "naughton@starwave.com"); ht.put("age", new Integer(30)); show(ht); } static void show(Dictionary d) { System.out.println("Title: " + d.get("title")); System.out.println("Author: " + d.get("author")); System.out.println("Email: " + d.get("email")); System.out.println("Age: " + d.get("age")); } }

Результат работы этого примера иллюстрирует тот факт, что метод show, параметром которого является абстрактный тип Dictionary, может извлечь все значения, которые мы занесли в ht внутри метода main. С:\> java HTDemo Title: The Java Handbook Author: Patrick Naughton Email: naughton@starwave.com Age: 30



HEIGHT = pixels



HEIGHT = pixels

WIDTH и HEIGHT - обязательные атрибуты, задающие начальный размер видимой области апплета.



Hello World



Hello World

Итак, вот ваша первая Java-программа: class HelloWorld { public static void main (String args []) { System. out. println ("Hello World"); } }

Для того, чтобы поработать с приведенными в книге примерами вам нужно получить по сети из Sun Microsystems и установить Java Developers Kit - пакет для разработки Java-приложений (http://java.sun.com/products/jdk).

Язык Java требует, чтобы весь программный код был заключен внутри поименованных классов. Приведенный выше текст примера надо записать в файл HelloWorld.java. Обязательно проверьте соответствие прописных букв в имени файла тому же в названии содержащегося в нем класса. Для того, чтобы оттранслировать этот пример необходимо запустить транслятор Java - javac, указав в качестве параметра имя файла с исходным текстом: С: \> javac HelloWorld.Java

Транслятор создаст файл HelloWorld.class с независимым от процессора байт-кодом нашего примера. Для того, чтобы исполнить полученный код, необходимо иметь среду времени выполнения языка Java (в нашем случае это программа java), в которую надо загрузить новый класс для исполнения. Подчеркнем, что указывается имя класса, а не имя файла, в котором этот класс содержится. С: > java HelloWorld Hello World

Полезного сделано мало, однако мы убедились, что установленный Java-транслятор и среда времени выполнения работают.



Хрупкие типы данных



Хрупкие типы данных

C++ получил в наследство от С все обычные типы данных последнего. Эти типы служат для представления целых и вещественных чисел различных размеров и точности. К несчастью, реальный диапазон и точность этих типов колеблется в зависимости от конкретной реализации транслятора. Поведение кода, который прекрасно транслируется и выполняется на одной машине, может радикально отличаться при смене платформы. Различные трансляторы C++ могут резервировать под целый тип 16, 32 или 64 бита в зависимости от разрядности машинного слова.

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



Идентификаторы



Идентификаторы

Идентификаторы используются для именования классов, методов и переменных. В качестве идентификатора может использоваться любая последовательность строчных и прописных букв, цифр и символов _ (подчеркивание) и $ (доллар). Идентификаторы не должны начинаться с цифры, чтобы транслятор не перепутал их с числовыми литеральными константами, которые будут описаны ниже. Java - язык, чувствительный к регистру букв. Это означает, что, к примеру, Value и VALUE - различные идентификаторы.