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

         

Зарезервированные слова Java



Таблица 2 - Зарезервированные слова Java

abstractbooleanbreakbytebyvalue
casecastcatchcharclass
constcontinuedefaultdodouble
elseextendsfalse final finally
floatforfuturegenericgoto
ifimplementsimportinnerinstanceof
intinterfacelongnativenew
nulloperatorouterpackageprivate
protectedpublicrestreturnshort
staticsuperswitchsyncronizedthis
throwthrowstransienttruetry
varvoidvolatilewhile

Отметим, что слова byvalue, cast, const, future, generic, goto, inner, operator, outer, rest, var зарезервированы в Java, но пока не используются Кроме этого, в Java есть зарезервированные имена методов (эти методы наследуются каждым классом, их нельзя использовать, за исключением случаев явного переопределения методов класса Object).



Зарезервированные имена методов Java



Таблица 3.1 - Зарезервированные имена методов Java



cloneequalsfinalizegetClasshashCode
notifynotifyAlltoStringwait


Управляющие последовательности символов



Таблица 3.2 - Управляющие последовательности символов

Управляющая последовательностьОписание
\dddВосьмеричный символ (ddd)
\uxxxxШестнадцатиричный символ UNICODE (xxxx)
\'Апостроф
\"Кавычка
\\Обратная косая черта
\rВозврат каретки (carriage return)
\nПеревод строки (line feed, new line)
\fПеревод страницы (form feed)
\tГоризонтальная табуляция (tab)
\bВозврат на шаг (backspace)


Операторы языка Java



Таблица 3.3 - Операторы языка Java

++=--=
**=//=
||=^^=
&&=%%=
>>=<<=
!!=++--
>>>>=<<<<=
>>>>>>=&&| |
===~?:
instanceof[ ] 


Элементы AWT и события Java 1.0, которые порождаются ими



Таблица 5. Элементы AWT и события Java 1.0, которые порождаются ими

ЭлементТип события (id)w
h
e
r
e
xyk
e
y
m
o
d
s
Смысл событияТип и значение переменной arg
ButtonACTION_EVENT    Пользователь нажал кнопкуString: обозначение кнопки
CheckboxACTION_EVENT     Пользователь активизировал флажокBoolean: новое состояние флажка
Choice (список выбора)ACTION_EVENT     Пользователь выбрал элемент спискаString: обозначение выбранного элемента
Element (элемент)GOT_FOCUS     Получение фокуса вводане используется
Element (элемент)KEY_ACTION*****Пользователь нажал функциональную клавишуне используется, поскольку key содержит константу клавиши
Element (элемент)KEY_ACTION_ RELEASE*****Пользователь отпустил функциональную клавишуне используется, поскольку key содержит константу клавиши
Element (элемент)KEY_PRESS*****Пользователь нажал клавишуне используется, поскольку key содержит ASCII-код клавиши
Element (элемент)KEY_RELEASE*****Пользователь отпустил клавишуне используется, поскольку key содержит ASCII-код клавиши
Element (элемент)LOST_FOCUS     Потеря фокуса вводане используется
Element (элемент)MOUSE_ENTER>***  Курсор мыши попал в область объекта класса Componentне используется
Element (элемент)MOUSE_EXIT***  Курсор мыши вышел из области объекта класса Componentне используется
Element (элемент)MOUSE_DOWN*** *Пользователь нажал кнопку мышине используется
Element (элемент)MOUSE_UP*** *Пользователь отпустил кнопку мышине используется
Element (элемент)MOUSE_MOVE*** *Пользователь переместил мышьне используется
Element (элемент)MOUSE_DRAG*** *Пользователь переместил мышь при нажатой кнопке мышине используется
List (список)ACTION_EVENT     Пользователь выполнил двойной щелчок мыши на элементе спискаString: обозначение выбранного элемента
List (список)LIST_SELECT     Пользователь выбрал элемент спискаInteger: индекс выбранного элемента
List (список)LIST_DESELECT     Пользователь убрал выделение с определенного элементаInteger: индекс элемента
Menu Item (меню)ACTION_EVENT     Пользователь выбрал пункт менюString: обозначение выбранного пункта
Scrollbar (полоса прокрутки)SCROLL_LINE_UP     Пользователь осуществил прокрутку вверх на строкуInteger: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки)SCROLL_LINE_DOWN     Пользователь осуществил прокрутку вниз на строкуInteger: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки)SCROLL_PAGE_UP     Пользователь осуществил прокрутку вверх на страницуInteger: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки)SCROLL_PAGE_DOWN     Пользователь осуществил прокрутку вниз на страницуInteger: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки)SCROLL_ABSOLUTE     Пользователь переместил ползунок полосы прокруткиInteger: позиция, до которой осуществляется прокрутка
Text Field (текст)ACTION_EVENT     Пользователь ввел текст и нажал [Enter].String: введенный текст
Window (окно)WINDOW_DESTROY     Окно закрытоне используется
Window (окно)WINDOW_ICONIFY     Окно представлено в виде пиктограммыне используется
Window (окно)WINDOW_DEICONIFY     Окно восстановленоне используется
Window (окно)WINDOW_MOVED **  Окно перемещеноне используется


Таблица 6. Типы событий, слушатели



Таблица 6. Типы событий, слушатели и методы слушателей в Java 1.1

Класс событияИнтерфейс слушателяМетоды слушателя
ActionEventActionListeneractionPerformed()
AdjustmentEventAdjustmentListeneradjustmentValueChanged()
ComponentEventComponentListenercomponentHidden()
componentMoved()
componentResized()
componentShown()
ContainerEventContainerListenercomponentAdded()
componentRemoved()
FocusEventFocusListenerfocusGained()
focusLost()
ItemEventItemListeneritemStateChanged()
KeyEventKeyListenerkeyPressed()
keyReleased()
keyTyped()
MouseEventMouseListenermouseClicked()
mouseEntered()
mouseExited()
mousePressed()
mouseReleased()
MouseMotionListenermouseDragged()
mouseMoved()
TextEventTextListenertextValueChanged()
WindowEventWindowListenerwindowActivated()
windowClosed()
windowClosing()
windowDeactivated()
windowDeiconified()
windowlconified()
windowOpened()
Для каждого интерфейса слушателей событий, содержащего несколько методов, в пакете java.awt.event определен простой класс-адаптер, который обеспечивает пустое тело для каждого из методов соответствующего интерфейса. Когда нужен только один или два таких метода, иногда проще получить подкласс класса-адаптера, чем реализовать интерфейс самостоятельно. При получении подкласса адаптера требуется лишь переопределить те методы, которые нужны, а при прямой реализации интерфейса необходимо определить все методы, в том числе и ненужные в данной программе. Заранее определенные классы-адаптеры называются так же, как и интерфейсы, которые они реализуют, но в этих названиях Listener заменяется на Adapter: MouseAdapter, WindowAdapter и т.д.

Как только реализован интерфейс слушателя или получены подклассы класса-адаптера, необходимо создать экземпляр нового класса, чтобы определить конкретный объект слушателя событий. Затем этот слушатель должен быть зарегистрирован соответствующим источником событий. В программах пакета AWT источником событий всегда является какой-нибудь элемент пакета. В методах регистрации слушателей событий используются стандартные соглашения об именах: если источник событий порождает события типа X, в нем существует метод addXListener () для добавления слушателя и метод removeXListener() для его удаления. Одной из приятных особенностей модели обработки событий Java 1.1 является возможность легко определять типы событий, которые могут порождаться данным элементом. Для этого следует просто просмотреть, какие методы зарегистрированы для его слушателя событий. Например, из описания API для объекта класса Button следует, что он порождает события ActionEvent. В таблице 7 приведен список элементов пакета AWT и событий, которые они порождают.


Таблица 7. Элементы пакета AWT



Таблица 7. Элементы пакета AWT и порождаемые ими события в Java1.1

ЭлементПорождаемое событиеЗначение
ButtonActionEventПользователь нажал кнопку
CheckBoxItemEventПользователь установил или сбросил флажок
CheckBoxMenuItemItemEventПользователь установил или сбросил флажок рядом с пунктом меню
ChoiceItemEventПользователь выбрал элемент списка или отменил его выбор
ComponentComponentEventЭлемент либо перемещен, либо он стал скрытым,либо видимым
 FocusEventЭлемент получил или потерял фокус ввода
 KeyEventПользователь нажал или отпустил клавишу
 MouseEventПользователь нажал или отпустил кнопку мыши, либо курсор мыши вошел или покинул область, занимаемую элементом, либо пользователь просто переместил мышь или переместил мышь при нажатой кнопке мыши
ContainerContainerEventЭлемент добавлен в контейнер или удален из него
ListActionEventПользователь выполнил двойной щелчок мыши на элементе списка
ItemEventПользователь выбрал элемент списка или отменил выбор
MenuItemActionEventПользователь выбрал пункт меню
ScrollbarAdjustmentEventПользователь осуществил прокрутку
TextComponentTextEventПользователь внес изменения в текст элемента
TextFieldActionEventПользователь закончил редактирование текста элемента
WindowWindowEventОкно было открыто, закрыто, представлено в виде пиктограммы, восстановлено или требует восстановления


Тег HTML <Applet>



Тег HTML <Applet>

Тег &ltapplet> используется для запуска апплета как из HTML-документа, так и из программы appletviewer. Программа appletviewer выполняет каждый найденный ей тег <applet> в отдельном окне, в то время как браузеры позволяют разместить на одной странице несколько апплетов. Синтаксис тэга <APPLET> в настоящее время таков : <APPLET CODE = appletFile OBJECT = appletSerialFile WIDTH = pixels HEIGHT = pixels [ARCHIVE = jarFiles] [CODEBASE = codebaseURL] [ALT = alternateText] [NAME = appletInstanceName] [ALIGN = alignment] [VSPACE = pixels] [HSPACE = pixels] > [< PARAM NAME = AttributeNamel VALUE = AttributeValuel >] [< PARAM NAME = AttributeName2 VALUE = AttributeValue2 >] [HTML-текст, отображаемый при отсутствии поддержки Java] </APPLET>



Тернарный оператор if-then-else



Тернарный оператор if-then-else

Общая форма оператора if-then-use такова: выражение1? выражение2: выражениеЗ

В качестве первого операнда - - может быть исполь-зовано любое выражение, результатом которого является значение типа boolean. Если результат равен true, то выполняется оператор, заданный вторым операндом, то есть, . Если же первый операнд paвен false, то выполняется третий операнд - . Второй и третий операнды, то есть и , должны воз-вращать значения одного типа и не должны иметь тип void.

В приведенной ниже программе этот оператор используется для про-верки делителя перед выполнением операции деления. В случае нулевого делителя возвращается значение 0. class Ternary { public static void main(String args[]) { int a = 42; int b = 2; int c = 99; int d = 0; int e = (b == 0) ? 0 : (a / b); int f = (d == 0) ? 0 : (c / d); System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); System.out.println("d = " + d); System.out.println("a / b = " + e); System.out.println("c / d = " + f); } }

При выполнении этой программы исключительной ситуации деления на нуль не возникает и выводятся следующие результаты: С: \>java Ternary а = 42 b = 2 с = 99 d = 0 a / b = 21 с / d = 0



TextArea



TextArea

Порой одной строки текста оказывается недостаточно для конкретной задачи. AWT включает в себя очень простой многострочный редактор обычного текста, называемый TextArea. Конструктор класса TextArea воспринимает значение типа String в качестве начального текста объекта. Кроме того, в конструкторе указывается число колонок и строк текста, которые нужно выводить. Есть три метода, которые позволяют программе модифицировать содержимое объекта TextArea: appendText добавляет параметр типа String в конец буфера; insertText вставляет строку в заданное отсчитываемым от нуля индексом место в буфере; rеplaceText копирует строку-параметр в буфер, замещая ею текст, хранящийся в буфере между первым и вторым параметрами-смещениями. Ниже приведена программа, создающая объект TextArea и вставляющая в него строку. /* <applet code = "TextAreaDemo" width=200 height=100> </applet> */ import java.awt.*; import java.applet.*; public class TextAreaDemo extends Applet { public void init() { setLayout(null); 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\n" + "that there are no obvious deficiencies.\n\n" + "C.A.R. Hoare\n\n" + "There's an old story about the person who wished\n" + "his computer were as easy to use as his telephone. \n" + "That wish has come true,\n" + "since I no longer know how to use my telephone. \n\n" + "Bjarne Stroustrup, AT&T (inventor of C++)"; TextArea text = new TextArea(val, 80, 40); add(text); text.setBounds(0, 0, width, height); } }



TextField



TextField

Класс TextField представляет собой реализацию однострочной области для ввода текста. Такие области часто используются в формах для пользовательского ввода. Вы можете "заморозить" содержимое объекта TextField с помощью метода setEditable, а метод isEditable сообщит вам, можно ли редактировать текст в данном объекте. Текущее значение объекта можно получить методом getText и установить методом setText. С помощью метода select можно выбрать фрагмент строки, задавая его начало и конец, отсчитываемые с нуля. Для выбора всей строки используется метод selectAll.

Метод setEchoChar задает символ, который будет выводиться вместо любых вводимых символов. Вы можете проверить, находится ли объект TextField в этом режиме, с помощью метода echoCharIsSet, и узнать, какой именно символ задан для эхо-печати, с помощью метода getEchoChar. Вот пример, в котором создаются классические поля для имени пользователя и пароля. /* <applet code = "TextFieldDemo" width=200 height=100> </applet> */ import java.awt.*; import java.applet.*; public class TextFieldDemo extends Applet { public void init() { setLayout(null); int width = Integer.parseInt(getParameter("width")); int height = Integer.parseInt(getParameter("height")); Label namep = new Label("Name : ", Label.RIGHT); Label passp = new Label("Password : ", Label.RIGHT); TextField name = new Text Field(8); TextField pass = new TextField(8); pass.setEchoChar('*'); add(namep); add(name); add(passp); add(pass); int space = 25; int w1 = width / 3; namep.setBounds(0, (height - space) / 2, w1, space); name.setBounds(w1, (height - space) / 2, w1, space); passp.setBounds(0, (height + space) / 2, w1, space); pass.setBounds(w1, (height + space) / 2, w1, space); } }

Обратите внимание, что в этом примере мы заменили устаревший в JDK 1.1 reshape на setBounds - TextFieldDemo.html. Вообще, в примерах могут встречаться вызовы Deprecated API, за что автор приносит извинения (после выхода Java 1.2, возможно, некоторые устаревшие функции будут действительно удалены, и тогда все примеры будут пересмотрены).



This в конструкторах



this в конструкторах

Очередной вариант класса Point показывает, как, используя this и совмещение методов, можно строить одни конструкторы на основе других. class Point { int х, у; Point(int х, int у) { this.x = х; this.у = у; } Point() { this(-1, -1); } }

В этом примере второй конструктор для завершения инициализации объекта обращается к первому конструктору.

Методы, использующие совмещение имен, не обязательно должны быть конструкторами. В следующем примере в класс Point добавлены два метода distance. Функция distance возвращает расстояние между двумя точками. Одному из совмещенных методов в качестве параметров передаются координаты точки х и у, другому же эта информация передается в виде параметра-объекта Point. class Point { int х, у; Point(int х, int у) { this.x = х; this. y = y; } double distance(int х, int у) { int dx = this.x - х; int dy = this.у - у; return Math.sqrt(dx*dx + dy*dy); } double distance(Point p) { return distance(p.x, p.y); } } class PointDist { public static void main(String args[]) { Point p1 = new Point(0, 0); Point p2 = new Point(30, 40); System.out.println("p1 = " + pi.x + ", " + p1.y); System.out.println("p2 = " + p2.x + ", " + p2.y); System.out.println("p1.distance(p2) = " + p1.distance(p2)); System.out.println("p1.distance(60, 80) = " + p1.distance(60, 80)); } }

Обратите внимание на то как во второй фороме метода distance для получения результата вызывается его первая форма. Ниже приведен результат работы этой программы: С:\> java PointDist р1 = 0, 0 р2 = 30, 40 р1.distance(p2) = 50.0 p1.distance(60, 80) = 100.0



Throw



throw

Оператор throw используется для возбуждения исключения . Для того, чтобы сделать это, нужно иметь объект подкласса клас-са Throwable, который можно либо получить как параметр оператора catch, либо создать с помощью оператора new. Ниже приведена общая форма оператора throw.



Throw ОбъектТипаThrowable;



throw ОбъектТипаThrowable;

При достижении этого оператора нормальное выполнение кода немед-ленно прекращается, так что следующий за ним оператор не выполня-ется. Ближайший окружающий блок try проверяется на наличие соот-ветствующего возбужденному исключению обработчика catch. Если такой отыщется, управление передается ему. Если нет, проверяется следующий из вложенных операторов try, и так до тех пор пока либо не будет най-ден подходящий раздел catch, либо обработчик исключений исполняю-щей системы Java не остановит программу, выведя при этом состояние стека вызовов. Ниже приведен пример, в котором сначала создается объект-исключение, затем оператор throw возбуждает исключительную ситуацию, после чего то же исключение возбуждается повторно - на этот раз уже кодом перехватившего его в первый раз раздела catch. class ThrowDemo { static void demoproc() { try { throw new NullPointerException("demo"); } catch (NullPointerException e) { System.out.println("caught inside demoproc"); throw e; } } public static void main(String args[]) { try { demoproc(); } catch(NulPointerException e) { System.out.println("recaught: " + e); } } }

В этом примере обработка исключения проводится в два приема. Метод main создает контекст для исключения и вызывает demoproc. Метод demoproc также устанавливает контекст для обработки исключе-ния, создает новый объект класса NullPointerException и с помощью опе-ратора throw возбуждает это исключение. Исключение перехватывается в следующей строке внутри метода demoproc, причем объект-исключение доступен коду обработчика через параметр e. Код обработчика выводит сообщение о том, что возбуждено исключение, а затем снова возбуждает его с помощью оператора throw, в результате чего оно передается обра-ботчику исключений в методе main. Ниже приведен результат, получен-ный при запуске этого примера. С:\> java ThrowDemo caught inside demoproc recaught: java.lang.NullPointerException: demo



Throws



throws

Если метод способен возбуждать исключения, которые он сам не об-рабатывает, он должен объявить о таком поведении, чтобы вызывающие методы могли защитить себя от этих исключений. Для задания списка исключений, которые могут возбуждаться методом, используется ключе-вое слово throws. Если метод в явном виде (т.е. с помощью оператора throw) возбуждает исключе-ние соответствующего класса, тип класса исключений должен быть ука-зан в операторе throws в объявлении этого метода. С учетом этого наш прежний синтаксис определения метода должен быть расширен следую-щим образом: тип имя_метода(список аргументов) throws список_исключений {}

Ниже приведен пример программы, в которой метод procedure пыта-ется возбудить исключение, не обеспечивая ни программного кода для его перехвата, ни объявления этого исключения в заголовке метода. Такой программный код не будет оттранслирован. class ThrowsDemo1 { static void procedure() { System.out.println("inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { procedure(); } }

Для того, чтобы мы смогли оттранслировать этот пример, нам при-дется сообщить транслятору, что procedure может возбуждать исключе-ния типа IllegalAccessException и в методе main добавить код для обработки этого типа исключений : class ThrowsDemo { static void procedure() throws IllegalAccessException { System.out.println(" inside procedure"); throw new IllegalAccessException("demo"); } public static void main(String args[]) { try { procedure(); } catch (IllegalAccessException e) { System.out.println("caught " + e); } } }

Ниже приведен результат выполнения этой программы. С:\> java ThrowsDemo inside procedure caught java.lang.IllegalAccessException: demo



Тип boolean



Тип boolean

В языке Java имеется простой тип boolean, используемый для хранения логических значений. Переменные этого типа могут принимать всего два значения - true (истина) и false (ложь). Значения типа boolean возвращаются в качестве результата всеми операторами сравнения, например (а < b) - об этом разговор пойдет в следующей главе. Кроме того, в главе 6 вы узнаете, что boolean - это тип, требуемый всеми условными операторами управления - такими, как if, while, do. boolean done = false;

Завершая разговор о простых типах...

Теперь, когда мы познакомились со всеми простыми типами, включая целые и вещественные числа, символы и логические переменные, давайте попробуем собрать всю информацию вместе. В приведенном ниже примере создаются переменные каждого из простых типов и выводятся значения этих переменных. class SimpleTypes { public static void main(String args []) { byte b = 0х55; short s = 0x55ff; int i = 1000000; long l = 0xffffffffL; char с = ' a' ; float f = .25f; double d = .00001234; boolean bool = true; System.out.println("byte b = " + b); System.out.println("short s = " +s); System.out.println("int i = " + i); System.out.println("long l = " + l); System.out.println("char с = " + с); System.out.println("float f = " + f); System.out.println("double d = " + d); System.out.println("boolean bool = " + bool); } }

Запустив эту программу, вы должны получить результат, показанный ниже: С: \> java SimpleTypes byte b = 85 short s = 22015 int i = 1000000 long l = 4294967295 char с = а float f = 0.25 double d = 1.234e-005 boolean bool = true

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



Типы исключений



Типы исключений

В вершине иерархии исключений стоит класс Throwable. Каждый из типов исключений является подклассом класса Throwable. Два непосредственных наследника класса Throwable делят иерархию подклассов исключений на две различные ветви. Один из них - класс Ехception - используется для описания исключительных ситуации, кото-рые должны перехватываться программным кодом пользователя. Другая ветвь дерева подклассов Throwable - класс Error, который предназначен для описания исклю-чительных ситуаций, которые при обычных условиях не должны перехватываться в пользовательской программе.



ToLowerCase и toUpperCase



toLowerCase и toUpperCase

Эта пара методов преобразует все символы исходной строки в нижний и верхний регистр, соответственно. "Hello".toLowerCase() -> "hello" "Hello".toUpperCase() -> "HELLO"



Трансляция классов в пакетах



Трансляция классов в пакетах

При попытке поместить класс в пакет, вы сразу натолкнетесь на жесткое требование точного совпадения иерархии каталогов с иерархией пакетов. Вы не можете переименовать пакет, не переименовав каталог, в котором хранятся его классы. Эта трудность видна сразу, но есть и менее очевидная проблема.

Представьте себе, что вы написали класс с именем PackTest в пакете test. Вы создаете каталог test, помещаете в этот каталог файл PackTest.Java и транслируете. Пока - все в порядке. Однако при попытке запустить его вы получаете от интерпретатора сообщение (). Ваш новый класс теперь хранится в пакете с именем test, так что теперь надо указывать всю иерархию пакетов, разделяя их имена точками - test.PackTest. Кроме того Вам надо либо подняться на уровень выше в иерархии каталогов и снова набрать , либо внести в переменную CLASSPATH каталог, который является вершиной иерархии разрабатываемых вами классов.



Тригонометрические функции



Тригонометрические функции

Приведенные ниже три функции имеют один параметр типа double, представляющий собой угол в радианах, и возвращают значение соответствующей тригонометрической функции. sin(double а) возвращает синус угла а, заданного в радианах. cos(double а) возвращает косинус угла а, заданного в радианах. tan(double а) возвращает тангенс угла а, заданного в радианах.

Следующие четыре функции возвращают угол в радианах, соответствующий значению, переданному им в качестве параметра. asin(double r) возвращает угол, синус которого равен г. acos(double r) возвращает угол, косинус которого равен г. atan(double r) возвращает угол, тангенс которого равен г. atan2(double a, double b) возвращает угол, тангенс которого равен отношению а/b.



Trim



trim

И, наконец, метод trim убирает из исходной строки все ведущие и замыкающие пробелы. "Hello World ".trim() -> "Hello World"



Try и catch



try и catch

Для задания блока программного кода, который требуется защитить от исключений, исполь-зуется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения которое вы хотите обрабатывать. class Exc2 { public static void main(String args[]) { try { int d = 0; int a = 42 / d; } catch (ArithmeticException e) { System.out.println("division by zero"); } } }

Целью большинства хорошо сконструированных catch-разделов долж-на быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние - такое, чтобы программу можно было продолжить так, будто никакой ошибки и не было (в нашем примере выводится предупреждение - division by zero).



Удаленный вызов методов



Удаленный вызов методов

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



Указатели



Указатели

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

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



Update



update

Используемый по умолчанию метод update класса Applet сначала закрашивает апплет цветом фона по умолчанию, после чего вызывает метод paint. Если вы в методе paint заполняете фон другим цветом, пользователь будет видеть вспышку цвета по умолчанию при каждом вызове метода update - то есть, всякий раз, когда вы перерисовываете апплет. Чтобы избежать этого, нужно заместить метод update. В общем случае нужно выполнять операции рисования в методе update, а в методе paint, к которому будет обращаться AWT, просто вызвать update.



URL



URL

URL (Uniform Resource Locators - однородные указатели ресурсов) - являются наиболее фундаментальным компонентом "Всемирной паутины". Класс URL предоставляет простой и лаконичный программный интерфейс для доступа к информации в Internet с помощью URL.

У класса URL из библиотеки Java - четыре конструктора. В наиболее часто используемой форме конструктора URL адрес ресурса задается в строке, идентичной той, которую вы используете при работе с браузером:



URL(String spec)



URL(String spec)

Две следующих разновидности конструкторов позволяют задать URL, указав его отдельные компоненты:

URL(String protocol, String host, int port, String file)

URL(String protocol, String host, String file)

Четвертая, и последняя форма конструктора позволяет использовать существующий URL в качестве ссылочного контекста, и создать на основе этого контекста новый URL.



URL(URL context, String spec)



URL(URL context, String spec)

В приведенном ниже примере создается URL, адресующий www-страницу (поставьте туда свой адрес), после чего программа печатает свойства этого объекта. import java.net.URL; class myURL { public static void main(String args[]) throws Exception { URL hp = new URL("http://coop.chuvashia.edu"); System.out. println("Protocol: " + hp.getProtocol()); System.out.printin("Port: " + hp.getPort()); System.out.println("Host: " + hp.getHost()); System.out.println("File: " + hp.getFile()); System.out.println("Ext: " + hp.toExternaLForm()); } }

Для того, чтобы извлечь реальную информацию, адресуемую данным URL, необходимо на основе URL создать объект URLConnection, воспользовавшись для этого методом openConnection().



URLConnection



URLConnection

URLConnection - объект, который мы используем либо для проверки свойств удаленного ресурса, адресуемого URL, либо для получения его содержимого. В приведенном ниже примере мы создаем URLConnection с помощью метода openConnection, вызванного с объектом URL. После этого мы используем import java.net.*; import java.io.*; class localURL { public static void main(String args[]) throws Exception { int c; URL hp = new URL("http", "127.0.0.1", 80, "/"); URLConnection hpCon = hp.openConnection(); System.out.println("Date: " + hpCon.getDate()); System.out.println("Type: " + hpCon.getContentType()); System.out.println("Exp: " + hpCon.getExpiration()); System.out.println( "Last M: " + hpCon.getLastModified()); System.out.println("Length: " + hpCon.getContentLength()); if (hpCon.getContentLength() > 0) { System.out.println("=== Content ==="); InputStream input = hpCon.getInputStream(); int i=hpCon.getContentLength(); while (((c = input. read()) != -1) && (--i > 0)) { System.out.print((char) c); } input.close(); } else { System.out.println("No Content Available"); } } }

Эта программа устанавливает HTTP-соединение с локальным узлом по порту 80 (у вас на машине должен быть и установлен Web-сервер) запрашивает документ по умолчанию, обычно это - index.html. После этого программа выводит значения заголовка, запрашивает и выводит содержимое документа.



Условные операторы



Условные операторы

Они хорошо Вам знакомы, давайте познакомимся с каждым из них в Java. if-else

В обобщенной форме этот оператор записывается следующим образом: if (логическое выражение) оператор1; [ else оператор2;]

Раздел else необязателен. На месте любого из операторов может стоять составной оператор, заключенный в фигурные скобки. Логическое выражение - это любое выражение, возвращающее значение типа boolean. int bytesAvailable; // ... if (bytesAvailable > 0) { ProcessData(); bytesAvailable -= n; } else waitForMoreData();

А вот полная программа, в которой для определения, к какому времени года относится тот или иной месяц, используются операторы if-else. class IfElse { public static void main(String args[]) { int month = 4; String season; if (month == 12 || month == 1 || month == 2) { season = "Winter"; } else if (month ==3 || month == 4 || month == 5) { season = "Spring"; } else if (month == 6 || month == 7 || month == 8) { season = "Summer"; } else if (month == 9 || month == 10 || month == 11) { season = "Autumn"; } else {season = "Bogus Month";} System.out.println( "April is in the " + season + "."); } }

После выполнения программы вы должны получить следующий результат: С: \> java IfElse April is in the Spring.



ValueOf



valueOf

Если вы имеете дело с каким-либо типом данных и хотите вывести значение этого типа в удобочитаемом виде, сначала придется преобразо-вать это значение в текстовую строку. Для этого существует метод val-ueOf. Такой статический метод определен для любого существующего в Java типа данных (все эти методы совмещены, то есть используют одно и то же имя). Благодаря этому не составляет труда преобразовать в стро-ку значение любого типа.



Ваш первый шаг



Ваш первый шаг

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



Вложенные операторы try



Вложенные операторы try

Операторы try можно вкладывать друг в друга аналогично тому, как можно создавать вложенные области видимости переменных. Если у оператора try низкого уровня нет раздела catch, соответствующего возбужденному исключению, стек будет развернут на одну ступень выше, и в поисках подходящего обработчика будут прове-рены разделы catch внешнего оператора try. Вот пример, в котором два оператора try вложены друг в друга посредством вызова метода. class MultiNest { static void procedure() { try { int c[] = { 1 }; c[42] = 99; } catch(ArrayIndexOutOfBoundsException e) { System.out.println("array index oob: " + e); } } public static void main(String args[]) { try { int a = args.length(); System.out.println("a = " + a); int b = 42 / a; procedure(); } catch (ArithmeticException e) { System.out.println("div by 0: " + e); } } }



Вы можете использовать оператор break



Внимание

Вы можете использовать оператор break только для перехода за один из текущих вложенных блоков. Это отличает break от оператора goto языка С, для которого возможны переходы на произвольные метки.

очевидно ожидают, что сейчас мы



Внимание

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

и StringBuffer объявлены final, что



Внимание

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

запустить сборщик мусора, вызвав метод



ВНИМАНИЕ!

При необходимости вы можете "вручную" запустить сборщик мусора, вызвав метод gc. Если вы хотите оценить, сколько памяти требуется для работы вашему коду, лучше всего сначала вызвать gc, затем free-Memory, получив тем самым оценку свободной памяти, доступной в системе. Запустив после этого свою программу и вызвав freeMemory внутри нее, вы увидите, сколько памяти использует ваша программа.

Вниз по течению



Вниз по течению

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



Void



void

У вас нередко будет возникать потребность в методах, которые возвращают значение того или иного типа: например, int для целых значений, float - для вещественных или имя класса для типов данных, определенных программистом. В нашем случае нужно просто вывести на экран строку, а возвращать значение из метода main не требуется. Именно поэтому и был использован модификатор void. Более детально этот вопрос обсуждается в главе 4.



VSPACE = pixels



VSPACE = pixels

HSPACE = PIXELS

Эти необязательные атрибуты задают ширину свободного пространства в пикселях сверху и снизу апплета (VSPACE), и слева и справа от него (HSPACE). Они трактуются точно так же, как одноименные атрибуты тега IMG.



Встроенные классы



Встроенные классы

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



Выполнение других программ



Выполнение других программ

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

В очередном примере используется специфичный для Windows вызов ехес, запускающий процесс notepad - простой текстовый редактор. В качестве параметра редактору передается имя одного из исходных файлов Java. Обратите внимание - ехес автоматически преобразует в строке-пути символы "/" в разделители пути в Windows - "\". class ExecDemo { public static void main(String args[]) { Runtime r = Runtime. getRuntime(); Process p = null; String cmd[] = { "notepad", "/java/src/java/lang/Runtime.java" }; try { p = r.exec(cmd); } catch (Exception e) { System.out.println("error executing " + cmd[0]); } } }



Вызов метода



Вызов метода

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



Взаимодействие подпроцессов



Взаимодействие подпроцессов

В Java имеется элегантный механизм общения между подпроцессами, основанный на методах wait, notify и notifyAll. Эти методы реализованы, как final-методы класса Object, так что они имеются в любом Java-классе. Все эти методы должны вызываться только из синхронизованных методов. Правила использования этих методов очень просты: wait - приводит к тому, что текущий подпроцесс отдает управление и переходит в режим ожидания - до тех пор пока другой под-процесс не вызовет метод notify с тем же объектом. notify - выводит из состояния ожидания первый из подпроцессов, вызвавших wait с данным объектом. notifyAll - выводит из состояния ожидания все подпроцессы, вызвавшие wait с данным объектом.

Ниже приведен пример программы с наивной реализацией проблемы поставщик-потребитель. Эта программа состоит из четырех простых классов: класса Q, представляющего собой нашу реализацию очереди, доступ к которой мы пытаемся синхронизовать; поставщика (класс Producer), выполняющегося в отдельном подпроцессе и помещающего данные в очередь; потребителя (класс Consumer), тоже представляющего собой подпроцесс и извлекающего данные из очереди; и, наконец, крохотного класса PC, который создает по одному объекту каждого из перечисленных классов. class Q { int n; synchronized int get() { System.out.println("Got: " + n); return n; } synchronized void put(int n) { this.n = n; System.out. println("Put: " + n); } } class Producer implements Runnable { Q q; Producer(Q q) { this.q = q; new Thread(this, "Producer").start(); } public void run() { int i = 0; while (true) { q.put(i++); } } } class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { while (true) { q.get(); } } } class PC { public static void main(String args[]) { Q q = new Q(); new Producer(q); new Consumer(q); } }

Хотя методы put и get класса Q синхронизованы, в нашем примере нет ничего, что бы могло помешать поставщику переписывать данные по того, как их получит потребитель, и наоборот, потребителю ничего не мешает многократно считывать одни и те же данные. Так что вывод программы содержит вовсе не ту последовательность сообщений, которую нам бы хотелось иметь: С:\> java PC Put: 1 Got: 1 Got: 1 Got: 1 Got: 1 Got: 1 Put: 2 Put: 3 Put: 4 Put: 5 Put: 6 Put: 7 Got: 7

Как видите, после того, как поставщик помещает в переменную n значение 1, потребитель начинает работать и извлекает это значение 5 раз подряд. Положение можно исправить, если поставщик будет при занесении нового значения устанавливать флаг, например, заносить в логическую переменную значение true, после чего будет в цикле проверять ее значение до тех пор пока поставщик не обработает данные и не сбросит флаг в false.

Правильным путем для получения того же результата в Java является использование вызовов wait и notify для передачи сигналов в обоих направлениях. Внутри метода get мы ждем (вызов wait), пока Producer не известит нас (notify), что для нас готова очередная порция данных. После того, как мы обработаем эти данные в методе get, мы извещаем объект класса Producer (снова вызов notify) о том, что он может передавать следующую порцию данных. Соответственно, внутри метода put, мы ждем (wait), пока Consumer не обработает данные, затем мы передаем новые данные и извещаем (notify) об этом объект-потребитель. Ниже приведен переписанный указанным образом класс Q. class Q { int n; boolean valueSet = false; synchronized int get() { if (!valueSet) try wait(); catch(InterruptedException e): System.out.println("Got: " + n); valueSet = false; notify(); return n; } synchronized void put(int n) { if (valueSet) try wait(); catch(InterruptedException e); this.n = n; valueSet = true; System.out.println("Put: " + n); notify(); } }

А вот и результат работы этой программы, ясно показывающий, что синхронизация достигнута. С:\> java Pcsynch Put: 1 Got: 1 Put: 2 Got: 2 Put: 3 Got: 3 Put: 4 Got: 4 Put: 5 Got: 5



While



while

Этот цикл многократно выполняется до тех пор, пока значение логического выражения равно true. Ниже приведена общая форма оператора while: [ инициализация; ] while ( завершение ) { тело; [итерация;] }

Инициализация и итерация необязательны. Ниже приведен пример цикла while для печати десяти строк . class WhileDemo { public static void main(String args[]) { int n = 10; while (n > 0) { System.out.println("tick " + n); n--; } } }



WIDTH = pixels



WIDTH = pixels









Window



Window

Класс Window во многом напоминает Panel за тем исключением, что он создает свое собственное окно верхнего уровня. Большая часть программистов скорее всего будет использовать не непосредственно класс Window, а его подкласс Frame.



Yield



yield

Вызов метода yield приводит к тому, что исполняющая система переключает контекст с текущего на следующий доступный подпроцесс. Это один из способов гарантировать, что низкоприоритетные подпроцессы когда-нибудь получат управление. sleep(int n)

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



Задание размеров графических изображений.



Задание размеров графических изображений.

Графические изображения вычерчиваются в стандартной для компьютерной графики системе координат, в которой координаты могут принимать только целые значения, а оси направлены слева направо и сверху вниз. У апплетов и изображений есть метод size, который возвращает объект Dimension. Получив объект Dimension, вы можете получить и значения его переменных width и height: Dimension d = size(); System.out.println(d. width + "," + d.height);

Простые методы класса Graphics

У объектов класса Graphics есть несколько простых функций рисования. Каждую из фигур можно нарисовать заполненной, либо прорисовать только ее границы. Каждый из методов drawRect, drawOval, fillRect и fillOval вызывается с четырьмя параметрами: int x, int y, int width и int height. Координаты х и у задают положение верхнего левого угла фигуры, параметры width и height определяют ее границы.



Замещение методов



Замещение методов

Новый подкласс Point3D класса Point наследует реализацию метода distance своего суперкласса (пример PointDist.java). Проблема заключается в том, что в классе Point уже определена версия метода distance(mt х, int у), которая возвращает обычное расстояние между точками на плоскости. Мы должны заместить (override) это определение метода новым, пригодным для случая трехмерного пространства. В следующем примере проиллюстрировано и совмещение (overloading), и замещение (overriding) метода distance. class Point { int х, у; Point(int х, int у) { this.x = х; this.у = у; } double distance(int х, int у) { int dx = this.x - х; int dy = this.у - у: return Math,sqrt(dx*dx + dy*dy); } double distance(Point p) { return distance(p.х, p.y); } } class Point3D extends Point { int z; Point3D(int х, int y, int z) { super(x, y); this.z = z; } double distance(int х, int y, int z) { int dx = this.x - х; int dy = this.y - y; int dz = this.z - z; return Math.sqrt(dx*dx + dy*dy + dz*dz); } double distance(Point3D other) { return distance(other.х, other.y, other.z); } double distance(int х, int y) { double dx = (this.x / z) - х; double dy = (this.у / z) - y; return Math.sqrt(dx*dx + dy*dy); } } class Point3DDist { public static void main(String args[]) { Point3D p1 = new Point3D(30, 40, 10); Point3D p2 = new Point3D(0, 0, 0); Point p = new Point(4, 6); System.out.println("p1="+p1.x+","+p1.y+","+p1.z); System.out.println("p2="+p2.x+","+p2.y+","+p2.z); System.out.println("p="+p.x+","+p.y); System.out.println("p1.distance(p2)="+p1.distance(p2)); System.out.println("p1.distance(4,6)="+ p1.distance(4,6)); System.out.println("p1.distance(p)="+p1.distance(p)); } }

Ниже приводится результат работы этой программы: С:\> Java Point3DDist p1 = 30, 40, 10 р2 = 0, 0, 0 р = 4, 6 p1.distance(p2) = 50.9902 p1.distance(4, 6) = 2.23607 p1.distance(p) = 2.23607

Обратите внимание - мы получили ожидаемое расстояние между трехмерными точками и между парой двумерных точек. В примере используется механизм, который называется динамическим назначением методов (dynamic method dispatch).



Зарезервированные ключевые слова



Зарезервированные ключевые слова

Зарезервированные ключевые слова - это специальные идентификаторы, которые в языке Java используются для того, чтобы идентифицировать встроенные типы, модификаторы и средства управления выполнением программы. На сегодняшний день в языке Java имеется 59 зарезервированных слов (см. таблицу 2). Эти ключевые слова совместно с синтаксисом операторов и разделителей входят в описание языка Java. Они могут применяться только по назначению, их нельзя использовать в качестве идентификаторов для имен переменных, классов или методов.



Знай свои типы



Знай свои типы

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