Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция
Скачать 25.04 Mb.
|
// Первый класс-наблюдатель. class Watcherl implements Observer { public void update(Observable obj, Object arg) { System.out.println("update() вызван, count равен " + ((Integer)arg).intValue()); } } // Второй класс-наблюдатель. class Watcher2 implements Observer { public void update(Observable obj, Object arg) { // По окончании выдать звуковой сигнал i f (((Integer)arg).intValue() == Готово" + 1 \ 7 1 ); } } // Наблюдаемый класс BeingWatched extends Observable { void counter(int period) { f o r ( ; period >=0; period--) { setChanged(); notifyObservers(new Integer(period)); try { Thread.s1e e p (100); } c a t c h (InterruptedException e) Ожидание прервано TwoObservers { public static void main(String a r g s []) { BeingWatched observed = new BeingWatched(); Watcherl observingl = new Watcherl(); Watcher2 observing2 = new Watcher2(); // Добавить оба наблюдателя observed.addObserver(observingl); observed.addObserver(observing2); Класс Observable и интерфейс позволяют реализовывать изощренные программные архитектуры, основанные на методологии документ- представление. Они также удобны в многопоточных программах 5 6 2 Часть II. Библиотека Классы Timer и Интересными полезным средством, предоставляемым пакетом java.util, является возможность планировать запуск задания на определенное время в будущем. Это обеспечивают классы Timer и TimerTask. Используя эти классы, вы можете создать поток, выполняющийся в фоновом режиме и ожидающий заданное время. Когда время истечет, задача, связанная с этим потоком, будет запущена. Различные параметры позволяют запланировать задачу на повторяющийся запуск либо на запуск по определенной дате. Хотя всегда существует возможность вручную создать задачу, которая будет запущена в определенное время с помощью класса Thread, все же классы Timer и TimerTask значительно упрощают этот процесс. Классы Timer и TimerTask работают вместе. Класс Timer используется для планирования выполнения задачи. Запланированная к выполнению задача должна быть экземпляром класса TimerTask. То есть, чтобы запланировать задачу, вы сначала создаете объект класса TimerTask, а затем планируете его запуск с помощью экземпляра класса Класс TimerTask реализует интерфейс Runnable. Это значит, что он может быть использован для создания потока выполнения. Его конструктор показан ниже. В классе T im e rT a sk определены методы, перечисленные в табл. 18.8. Обратите внимание на то, что метод r u n () является абстрактным, а это означает, что он должен быть переопределен. Метод r u n ( ) , определенный в интерфейсе R u n n a b le , содержит исполняемый код. То есть простейший способ создать задачу для таймера — это расширить класс T im e rT a sk и переопределить метод r u n (Таблица 18.8. Методы, определенные в классе T i m e r T a s Метод , ’ . : Описание __________ boolean cancel () Прерывает задание. Возвращает значение если выполнение задания прервано. В противном случае возвращает значение f a l s e abstract void run () Содержит код задания таймера scheduledExecut ionTime () Возвращает время, на которое последний раз планировался запуск задания______________________ Как только задача создана, она планируется для выполнения объектом класса Timer. Вот как выглядят конструкторы класса Timer. T i m e r () Timer(boolean потокД) Timer(String имяПотока) Timer(String имяПотока, boolean потокД) Первая версия создает объект класса Timer и затем запускает его как обычный поток. Вторая использует поток-демон, если параметр потокД равен true. Поток- демон будет выполняться только до тех пор, пока выполняется остальная часть программы. Третий и четвертый конструкторы позволяют указывать имя объекта класса Timer. Методы класса Timer перечислены в табл. Таблица 18.9. Методы, определенные в классе T i m e r ' - * Описание " У ‘ г У У . void cancel (Прерывает поток таймера p u r g e (Удаляет прерванные задания из очереди таймера Глава 18. Пакет java.util: прочие служебные классы 5 6 Окончание табл. 18 Описание schedule(TimerTask задача Т , long ожидать schedule(TimerTask задача Т , long ожидать повторять задача Т , Date врем яЗап уска) void schedule(TimerTask задача Т , Date время Запуска повторять задача Т , long ожидать повторять задача Т , Date время Запуска повторять Задание задача Т планируется к выполнению через период в миллисекундах, переданный в параметре ожидать Задание зада чаТ планируется к выполнению через период в миллисекундах, переданный в параметре ожидать. Задание затем выполняется повторно периодически — каждые повторять миллисекунд Задание зада чаТ планируется к выполнению на время, указанное в параметре вр емяЗапуска Задание зада чаТ планируется к выполнению на время, указанное в параметре времяЗапуска. Задание затем выполняется повторно периодически — каждые повторять миллисекунд Задание зада чаТ планируется к выполнению через период в миллисекундах, переданный в параметре ожидать. Задание затем выполняется повторно периодически — каждые повторять миллисекунд. Время каждого повтора задается относительно первого запуска, а не предыдущего. То есть общее время выполнения остается фиксированным Задание зада чаТ планируется к выполнению на время, указанное в параметре времяЗапуска. Задание затем выполняется повторно периодически — каждые повторять миллисекунд. Время каждого повтора задается относительно первого запуска, а не предыдущего. То есть общее время выполнения остается фиксированным__________ Как только объект класса Timer создан, запуск планируется вызовом его метода schedule () . Как показано в табл. 18.9, существует несколько форм метода schedule () , позволяющих запланировать задание разными способами. Если вы создаете задание, не являющееся демоном, то, возможно, захотите вызвать метод cancel () для его прерывания при завершении программы. Если вы не сделаете этого, то ваша программа может зависнуть на некоторое время. В следующей программе демонстрируется работа с классами Timer и TimerTask. В ней определяется задание таймера, метод run () которого отображает сообщение Задание таймера выполняется. Это задание планируется на запуск каждые полсекунды после начальной паузы в одну секунду Демонстрация применения Timer и TimerTask. import java.util.*; class MyTimerTask extends TimerTask { public void run() Задание таймера выполняется TTest { public static void main(String a r g s []) { MyTimerTask myTask = new MyTimerTask(); 5 6 Часть II. Библиотека Java Timer myTimer = new T i m e r (); /* Устанавливает начальную паузу в 1 секунду затем повторяется каждые полсекунды, 1000, 500); try { Thread.sleep(5000); } catch (InterruptedException exc) {} myTimer.c a Класс Класс Currency инкапсулирует информацию о валюте. Он не определяет конструкторов. Методы класса Currency перечислены в табл. 18.10. В следующей программе демонстрируется использование класса Currency. // Демонстрация применения Currency, import java.util.*; class CurDemo { public static void main(String a r g s []) { Currency с = Символ " + с Количество дробных разрядов по умолчанию "+ с Рассмотрим вывод этой программы. С имвол: Количество дробных разрядов по умолчанию Таблица 18.10. Методы, определенные в классе C u r r e n c ст. Л Л Г . » ' J k a L & ^ . ж ж ^ А ^ А ё ё М . static Set () Добавлено в JDK 7) String getCurrencyCode () Возвращает код валюты в стандарте ISO 4217 i n t Возвращает количество десятичных знаков после getDef aultFractionDigits () точки, которые обычно используются сданной валютой. Например, для доллара это будет 2 знака t г ing ge t Di sp 1 ayName () Возвращает название запрошенной валюты для заданного по умолчанию региона. (Добавлено в JDK 7) S t г i ng Возвращает название запрошенной валюты для заданного региона. (Добавлено bJDK регион Currency Возвращает объект класса Currency для региональных данных, указанных параметром объектРегиона) объектРегиона Глава 18. Пакет java.util: прочие служебные классы 5 6 Окончание табл. 18.10 Описание '■гм.п.пАм,и, .йтмУчттгг й к static Currency getInstance(String код) Возвращает объект класса Currency, ассоциированный с кодом валюты, переданным в параметре toString() String getSymbol(Locale объектРегиона) String getSymbol() int getNumericCode() код Возвращает числовой код (как определено стандартом ISO 4217) для запрошенной валюты. (Добавлено в JDK Возвращает символ валюты (такой, как $) для вызывающего объекта Возвращает символ валюты (такой, как $) для региональных данных, указанных параметром объектРегиона Возвращает код валюты вызывающего объекта Класс В центре системы поддержки форматированного вывода находится класс Formatter. Он предлагает преобразования формата, позволяющие отображать числа, строки, время и даты практически в любом виде по вашему желанию. Он работает подобно функции C/C++ printf () , из чего следует, что если вы знакомы с языком C/C++, то изучение класса Formatter для вас будет очень простым. Это также упрощает преобразование кода C/C++ в Java. Если вы незнакомы с языком C/C++, все равно будет достаточно просто научиться форматировать данные. На заметку Несмотря на то что класс Formatter очень похож на функцию C/C++ printf (), существуют некоторые отличия и усовершенствования. Таким образом, даже если вы имеете опыт использования языка C/C++, все равно рекомендуется внимательно прочитать этот раздел. Прежде чем можно будет использовать класс Formatter для форматирования вывода, следует создать его объект. В общем случае объект класса Formatter работает, преобразуя бинарную форму данных, используемых программой, в форматированный текст. Он явно сохраняет форматированный текст в буфере, содержимое которого может быть доступно вашей программе в любой момент, когда понадобится. Можно позволить объекту класса Formatter создавать этот буфер автоматически или же указать его явно при создании объекта класса Formatter. Можно также заставить объект класса Formatter направлять свой буфер в файл. Класс Formatter определяет много конструкторов, позволяющих создавать его объекты разными способами буфер буфер Locale регион имяфайла) throws FileNotFoundException Formatter(String имяфайла, String наборсимволов) throws FileNotFoundException, UnsupportedEncodingException Formatter(File выхФайл) throws FileNotFoundException Formatter(OutputStream выхПоток) Конструкторы класса F o r m a t t e r 5 6 6 Часть II. Библиотека Здесь параметр буфер указывает буфер для форматированной строки. Если буфер пуст, то объект класса F o r m a tte r автоматически резервирует объект класса S t r i n g B u f f e r для хранения отформатированной строки. Параметр регион указывает региональные данные. Если региональные данные не заданы, используются региональные данные по умолчанию. Параметр им яф айла определяет имя файла, который будет принимать форматированный вывод. Параметр набор символов указывает набор символов. Если не указано никакого набора символов, то используется набор символов по умолчанию. Параметр вы хФ айл представляет собой ссылку на открытый файл, который должен принимать вывод. Параметр выхП оток задает ссылку на выходной поток, куда будет направлен вывод. Когда используется файл, вывод также пишется в файл. Возможно, наиболее широко применяется первый конструктор, который не имеет параметров. Он автоматически использует региональные данные по умолчанию и резервирует объект класса S t r i n g B u f f e r для хранения отформатированного вывода. Методы класса F o r m a t t e Класс F o rm a tte r определяет методы, перечисленные в табл. Таблица 18.11. Методы, определенные в классе F o r m a t t e r Метод Описание void c l o s e () void f l u s h () Formatter format(String формСтрока, Object ... аргументы format(Locale регион формСтрока, Object ... аргументы ioExcep- t i o n () Locale l o c a l e () Appendable o u t () String to S t r i n g (Закрывает вызываемый объект класса Formatter. Это приводит к тому, что все ресурсы, используемые объектом, освобождаются. После закрытия объекта класса Formatter его больше нельзя использовать. Попытка использования закрытого объекта класса Formatter приводит к передаче исключения Сбрасывает буфер формата. Это приводит к тому, что весь вывод, находящийся в буфере, записывается в адресат. В основном, используется для объекта класса Formatter, примененного к файлу Форматирует аргументы, переданные в аргументы, в соответствии со спецификаторами формата, содержащимися в формСтрока. Возвращает вызываемый объект Форматирует аргументы, переданные в аргументы, в соответствии со спецификаторами формата, содержащимися в формСтрока. При форматировании используются региональные данные, определенные в параметре регион. Возвращает вызываемый объект Если лежащий в основе объект, указанный в качестве адресата, передает исключение IOException, возвращается это исключение. В противном случае возвращается значение Возвращает региональные данные вызывающего объекта Возвращает ссылку на лежащий в основе объект, который назначен в качестве адресата для вывода Возвращает объект класса String, содержащий форматированный вывод Глава 18. Пакет java.util: прочие служебные классы 6 Основы форматирования После того как вы создали объект класса F o rm a tte r, его можно применять для создания форматированных строк. Для этого используйте метод fo rm at ( ) . Его наиболее часто используемая версия показана ниже o rm a tte r f o r m a t (S t r i n g ф ормС т рока, O b je c t . . . аргументы Строка формСтрока состоит из элементов двух типов. Первый тип — символы, которые просто копируются в выходной буфер. Второй тип — спецификаторы формата, определяющие способ, в соответствии с которым должны отображаться последующие аргументы. В простейшей форме спецификатор формата начинается со знака процента с последующим спецификатором преобразования Все спецификаторы преобразования формата состоят из единственного символа. Например, спецификатор формата для числа с плавающей точкой выглядит как % f . В общем случае должно быть столько аргументов, сколько есть спецификаторов формата, и соответствие аргументов устанавливается слева направо. Например, рассмотрим следующий фрагмент кода fmt = new Форматировать %s очень просто %d с помощью Jav a ", 10, Приведенный фрагмент кода создает объект класса F o rm a tte r, содержащий следующую строку. Ф орм атировать с помощью J a v a очень просто В этом примере спецификаторы формата %s, %d и % f замещаются аргументами, следующими за строкой формата. То есть %s заменяется нас помощью J a v a " , %d — H a l0 ,a % f — на 9 8 .6 . Все остальные символы используются, как есть. Как вы можете ожидать, спецификатор параметра %s указывает строку, а спецификатор %d — целое число. Как уже упоминалось, спецификатор %f означает число с плавающей точкой. Метод fo rm at () принимает широкое разнообразие спецификаторов формата, которые показаны в табл. 18.12. Обратите внимание на то, что многие спецификаторы имеют и заглавную, и строчную формы. Когда используется заглавная форма, буквы отображаются в верхнем регистре. Во всем остальном формы эквивалентны. Важно понимать, что Java проверяет каждый спецификатор формата на соответствие типу аргумента. Если аргумент не соответствует, передается исключение I lle g a lF o r m a t E x c e p t io n Таблица 18.12. Спецификаторы формата %а %А Шестнадцатеричное с плавающей точкой %Ь %В Булево %h %Н %с %d Символ Десятичное целое Хеш-код аргумента %е Научная нотация %Е 5 6 Часть II. Библиотека Окончание табл. Спецификатор ; формата -г, Применяемое преобразование ! ; " П I * J ,| Десятичное с плавающей точкой %g Использует либо е, либо %f , в зависимости оттого, что короче %G %о Восьмеричное целое %n Вставляет символ перевода строки %s Строка %S %t Время и дата %T %x Шестнадцатеричное целое %X %% Вставляет символ После того как отформатируете строку, можете получить ее методом t o S t r i n g (). Например, следующий оператор получает форматированную строку, содержащуюся в объекте fm t. String str = fm t Конечно, если вы просто хотите отобразить форматированную строку, нет причин вначале присваивать ее объекту класса S t r i n g . Например, когда объект класса F o r m a t t e r передается методу p r i n t l n ( ) , то автоматически вызывается его метод t o S t r i n g ( ) Ниже приведена короткая программа, которая собирает все вместе, демонстрируя создание и отображение отформатированной строки Очень простой пример применения Formatter, import java.util.*; |