[an error occurred while processing this directive]

Занятие 6

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

В основу создания языка Java положены следующие ключевые концепции:

Подчеркнем еще раз, что апплеты работают только с броузером. Перед тем как запускать апплет, пользователь должен загрузить броузер, в котором есть встроенная поддержка Java - так называемый ''Java-enabled'' броузер, например, NetscapeNavigator 2.0 или MicrosoftExplorer 3.0 или их более поздние версии. Кроме того, можно использовать специальную программу, входящую в состав комплекта разработчика Java (JDK), которая носит название Appletviewer. С ее помощью можно быстро запустить и протестировать свои апплеты.

Апплеты

Небольшие мобильные программы на языке Java, которые можно передавать по сети и исполнять на компьютере пользователя, называются апплетами. Для встраивания вызовов апплетов в текст HTML-документа и отведения места для отображаемой апплетом информации в HTML был введен контейнер APPLET, который начинается тегом <applet ....> и кончается тегом </applet>. В общем виде документ, содержащий ссылки на апплеты будет выглядеть так:

<html>
<head>
<title>Документ со встроенной ссылкой на applet.</title>
</head>
<bodybgcolor=#FFFFFF>
<center>
<h1>Документ со встроенным апплетом helloJava</h1>
<hr>
<appletcode=hello.classwidth=200 height=100>
Applet будет отображаться в этом месте, если Ваш броузер интерпретирует Java
</applet>
<hr>
</center>
</body>
</html>

В данном примере после заглавия документа (тег h1) и горизонтальной черты начинается поле апплета шириной 200 пикселей и высотой 100 пикселей. В данное поле загружается applet с именем hello (файл hello.class). Текст между тегами начала и конца контейнера applet используется для размещения встраиваемых контейнеров и текста, который отображается броузерами, не позволяющими использовать Java.

В результате ссылки на такой документ сначала будет загружен текст документа. Затем будет обнаружен контейнер applet, и произойдет загрузка кода апплета. Файл hello.class должен в этом случае находиться там же, где и HTML-файл, в котором есть на него ссылка. После приема апплета броузер отведет под него место в своей рабочей области и только после этого начнет его исполнение.

В общем случае контейнер APPLET имеет следующий вид:

<applet
 [codebase = codebase_url]
 code = applet.class
 [alt = text]
 [name= applet_name]
 width = number_of_pixels
 height = number_of_pixels
 [align = alignment]
 [vspace=number_of_picsels]
 [hspace=number_of_pixels] >
[<paramname=param_namevalue=param_value>]
...
[HTMLtext]
</applet>

Параметр codebase задает базу для поиска кода апплета, code - это имя файла апплета, которое должно иметь расширение class, alt - альтернативный текст - отображается в том случае, когда выполнение апплета запрещено, name - имя контейнера applet, используется для ссылки на контейнер, width - ширина области отображения апплета, height - высота области отображения апплета, align - управляет выравниванием области отображения апплета внутри рабочей области броузера, vspace и hspace - указывают на отступ от текста HTML-документа (вертикальный и горизонтальный, соответственно).

Использование контейнера PARAM позволяет передавать параметры внутрь апплета из HTML-документа. Это аналогично вызову команды с различными аргументами командной строки. Для того, чтобы получить эти параметры внутри апплета следует использовать метод getParameter ():

<appletcode=hello.classwidth=200 hieght=100>
<paramname=imagevalue=gif>
</applet>
.....
classhelloextendsApplet
 {
 publicvoidinit ()
 {
 Stringimage_type = getParameter ("image");
 ....
 }
 ...
 }

Из атрибутов контейнера APPLET обязательными являются только code, width и height. Все остальные атрибуты (они заключены в квадратные скобки "[]") можно опускать. Большинство систем разработки Java-программ сами генерируют HTML-документ, точнее его макет, для тестирования Java-апплетов. Так поступают, например, в ADK (AppletDevelopmentKit) компании IBM.

Для получения URL документа, из которого вызван applet можно использовать методы getDocumentBase и getCodeBase. Первый определяет базу адреса для документа, в то время как второй определяет базу адреса самого апплета. Применение этих методов необходимо для обращения за данными (текст или графика), которые могут храниться там же, где и документ/applet.

В отличии от application апплеты имеют совсем другую схему инициализации. В них нет метода main. Любой applet расширяет класс Applet. В этом классе есть ряд методов, которые программист замещает при написании своей программы. При этом методы апплета выполняются броузером в определенном порядке.

Сразу после загрузки апплета вызывается метод init (). В нем программист инициализирует переменные и другие параметры, которые будут использоваться апплетом. Например, здесь можно присвоить всем строковым константам определенные значения, проинициализировать числовые константы. Однако, в init () можно выполнить и ряд других подготовительных операций, которые могут показаться непривычными для тех кто не работал в сети, например, загрузить графические образы в буферы для последующего монтирования в мультипликацию.

Сразу после метода init () вызывается метод start (). Этот метод фактически запускает исполнение основного кода апплета. Как мы видели в примере 3.20, многопоточный applet запускает потоки именно в методе start (). Если applet был остановлен, а потом запущен снова, то в этом случае тоже вызывается метод start (). С метода start () возобновляется выполнение апплета и в том случае, если пользователь покидал страницу HTML, а потом к ней вернулся. Последний момент очень важен. При возвращении метод init () выполняться не будет. Следовательно, не будет инициализации параметров. Программа начнет, точнее продолжит, работать из того же положения, в котором она была в момент перехода на другую HTML-страницу. При написании апплетов нужно очень аккуратно работать с методом start () и методом stop (), который рассмотрим ниже, так как возможна ситуация, когда при уходе со страницы с апплетом, апплет остается в памяти и продолжает исполняться. Такая "закладка" может не очень понравится пользователям сети.

Метод stop () вызывается в том случае, когда пользователь покидает страницу с апплетом. В этом методе обычно указываются все потоки, которые следует остановить при переходе на другую страницу. При возврате все эти потоки должны быть снова запущены в методе start ().

Наиболее радикально удаляет апплеты метод destroy (). Данный метод освобождает все ресурсы, которые занимает applet.

Следующую группу методов составляют методы отображения информации в рабочей области апплета. К их числу относятся методы paint (), update () и repaint ().

Метод paint () отвечает за целостность изображения в рабочем окне апплета. Если в результате наложения окон или других событий произошло повреждение изображения, то paint () перерисовывает изображение.

Метод update () для реального управления выводом изображения. Если все методы рисования применять в методе paint (), то рабочая область апплета будет мигать. Происходит это из-за того, что сначала update () заполняет всю рабочую область цветом фона умолчания, а уж потом начинается рисование. Мигание обычно вызвано тем, что в paint () определяют другой, отличный от цвета умолчания цвет фона. Для того, чтобы этого не происходило надо заместить метод update (), а в методе paint () просто его вызывать:

importjava.applet.*;
importjava.awt.*;
publicclassmultiextendsAppletimplementsRunnable
{
...
publicvoidupdate (Graphicsg)
 {
 ....
 }
publicvoidpaint (Graphicsg)
 {
 this.update (g);
 }
}

Методы paint () и update () не дают, тем не менее, ритмичности изменения информации. Поэтому для принудительного перерисовывания изображения используется метод repaint (). Этот метод в большинстве случаев не надо замещать, а надо просто вставлять внутрь своего кода, там где требуется изменение изображения в рабочей области апплета. Этот метод вызывает update (), который собственно и изменяет изображение. Для того, чтобы изменения происходили ритмично существует repaint (time), где time задает в миллисекундах время, относительно вызова repaint (), за которое изображение должно быть перерисовано. Другая форма repaint (x,y,w,h) позволяет ограничить область изменения изображения прямоугольником с координатами северо-восточного угла x, y и шириной и высотой w, h. Имеется и комбинация - repaint (time,x,y,w,h).

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

Типы данных Java и литералы

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

К простым типам относят следующие восемь типов:

При этом их можно разделить на четыре группы: целые (short, int, long, byte), вещественные (float, double), символьные (char) и логические (boolean). Первые две группы при этом обычно называют числовыми типами данных.

Целые типы соответствуют стандарту ANSI для языка C (byte - 8 байт, short - 16 байт, int - 32 байта и long - 64 байта). При этом размер памяти, занимаемой целыми числами, и их разрядность в Java не совпадают. В коде Sun типы byte и short хранятся как 32-х разрядные числа. Поэтому ориентироваться на тип при определении общего размера требуемых ресурсов не стоит. Тип скорее нужен для контроля диапазона записываемых в переменную чисел, чем для экономии места. Ниже приведены примеры инициализации целых переменных.

inta, i =10, o=012, h =0xA; // инициализация константой 10
shortb;
longl, r = 0x7ffffffffffffffL;
byteb, c = 0x61; // переменной c присвоено значение, равное коду буквы "a".

Вещественные типы реализуют числа с плавающей точкой и имеют float - 32 разряда и double - 64 разряда. Ниже приведены переменные вещественных типов и литералы для их инициализации.

floata, b=0, b1=.09, x=6.0e23, z=.79E-10, h=0.39F, r=047e+20f
doublev, w=0.1D, s=32.0d;

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

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

Символы в Java представляются переменными типа char. Реализация типа char представляет из себя двухбайтовый код Unicode. Это принципиально отличает Java от C, Fortran, Pascal, Basic и других традиционных языков программирования. Очевидно, что использовать char для анализа потоков байтов нельзя. Потоки байтов, которые можно считать из текстовых файлов или получить по сети, требуют преобразования в массивы символов. Для работы с такими массивами используются специальные классы: String и StringBuffer.

сharch='\0061'; // буква "a"
charchr = '\\' ; // обратная косая черта. "\" маскирует особое значение \

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

inta[];
charch[] = newchar[12];
longv[][] = newlong[2][3];
intx[] = { 1,2,3,4 };
charc[] = newchar[3];
charn[] = { 'c', 'b','r' };

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

Stringstr = newString();
chara[] = {'h','u','r','a'};
Stringstr1 = newString(a);
Stringstr2 = newString(s,0,3); // str2 = "hur"
Stringstr3 = "hura";

Для объектов класса String определены методы. Рассмотрим только некоторые из них. Метод equals позволяет сравнить содержание объектов класса String. При этом сравниваются символы в одинаковых позициях строк. Этот метод следует отличать от оператора "==", т.к. последний сравнивает указатели на значения, а не сами строки. В этом хорошо проявляется назначение класса String как класса для работы с неизменяемыми строками. Реально существует массив строковых констант, на которые ссылаются объекты класса String. Если два объекта ссылаются на одну и туже константу, то логический оператор "==" выдаст значение true. Если ссылка будет на разные участки памяти, которые содержат, например, константу, а второй операнд подстроку, равную по значению константе, то оператор "==" выдаст результат false.

Strings1 = "kuku1";
Strings2 = "kuku2";
if(s1.equals(s2))
 {
 ...
 }
else
 {
 }
..........
Strings3 ="Hello";
Strings4 = newString(s3);
if(s3==s4)
 {
 ... // блок исполняться не будет.
 }

Слияние строк осуществляется посредством использования оператора "+".

Strings = "Hello"+"Java.";

Класс StringBufferпредназначен для преобразования строк. Фактически, в предыдущем примере при слиянии двух строк используется преобразование объекта String в объект StringBuffer, а затем обратное преобразование. По умолчанию конструктор инициализирует объект типа StringBuffer объектом типа String и резервирует еще 16 символов для возможности изменения значения объекта. Можно максимальный размер буфера определить вручную.

StringBuffersb = newStringBuffer(); // 16 символов
StringBuffersb1 = newStringBuffer("Kuku"); // 20 символов
StringBuffersb2 = newStringBuffer(100); // 100 символов

Длину буфера символов можно определить методом length. Длину буфера можно изменять. Для этого используется метод setLength. Для добавления символов в буфер используется метод append. Если надо вставить внутрь буфера символы, то тогда следует пользоваться методом append.

StringBuffersb = newStringBuffer("It`satest");
sb.append(" string");
sb.setLength(30);
sb.insert(6,"nexampleof")

В этом примере для того, чтобы в буфер поместилось новое значение, пришлось изменить размер буфера.

Назад | Содержание | Вперед

  [an error occurred while processing this directive]