Назад
Вперед
1.9. Применение блока finally
В примере демонстрируются использование блока
finally при обработке исключений.
Исходный текст примера
Архив проекта для Java WorkShop 2.0
Немного теории
В некоторых случаях при обработке исключений с
применением блоков try-catch имеет смысл
дополнительно предусмотреть блок finally. Этот блок
выполняется всегда, независимо от того,
произошло исключение в процессе работы блока try
или нет.
Наилучшее применение для блока finally -
освобождение ресурсов, заказанных программой
перед возникновением исключений. Хотя система
сборки мусора автоматически освобождает
ненужную более оперативную память, открытые
потоки, например, следует закрывать явным
образом при помощи метода close.
Описание примера
В нашем примере мы создаем цикл ввода целых
чисел. После выполнения операции деления числа 100
на введенное число полученный результат
записывается в буферизованный выходной поток.
Если ввести нулевое значение или строку,
которую нельзя интерпретировать как число,
возникает исключение. В результате цикл ввода и
записи чисел в файл прерывается. Обработчик
исключения выводит на консоль сообщение об
ошибке. Что же касается выходного потока, то он
закрывается в блоке finally.
Так как программа работает с потоками, она
импортирует класс java.io.*. Дополнительно для
разбора введенной текстовой строки мы
используем класс java.util.*:
import java.io.*;
import java.util.*;
В главном классе программы мы определили
статическое поле os класса DataOutputStream:
static DataOutputStream os;
В него будет записана ссылка на выходной поток.
Создание потока выполняется следующим образом:
try
{
os = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("log.txt")));
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
Здесь мы создаем объект класса FileOutputStream,
привязывая его к файлу. На базе этого объекта
образуется буферизованный выходной поток класса
BufferedOutputStream, который в свою очередь используется
как базовый для создания потока класса DataOutputStream.
В нашем примере мы намеренно применили
буферизованный поток, так как если такой поток не
закрыть перед завершением программы, данные не
будут переписаны из буфера в файл.
Цикл ввода чисел и записи результата
вычислений в поток мы полностью разместили в
блоке try. В сокращенном виде этот цикл
представлен ниже:
try
{
while(true)
{
. . .
}
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
finally
{
try
{
System.out.println("close");
os.close();
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}
Если в результате возникновения исключения
цикл аварийно завершается, блок finally закрывает
поток os. Заметим, что этот поток закрывается и в
случае нормального завершения цикла, так как
блок finally выполняется в любом случае - произошло
исключение, или нет.
Теперь о том, что происходит внутри цикла.
Ввод символов с консоли выполняется следующим
образом:
byte bKbd[] = new byte[256];
String szStr = "";
int iCnt = System.in.read(bKbd);
szStr = new String(bKbd, 0, iCnt);
Строка szStr создается на базе массива байт,
причем ее длина равна количеству введенных
символов iCnt.
Для удаления из строки символов \r и \n мы создаем
объект класса StringTokenizer. Через второй параметр
конструктору передается строка
символов-разделителей:
StringTokenizer st;
st = new StringTokenizer(szStr, "\r\n");
При помощи метода nextElement мы извлекаем нужную
нам часть строки и затем записываем ее в поле szStr:
szStr =
new String((String)st.nextElement());
Далее строка преобразуется в значение типа int:
Integer intVal = new Integer(szStr);
int i;
i = intVal.intValue();
Если в результате получается число 777, работа
цикла завершается нормальным образом:
if(i == 777)
break;
Любое другое число используется как делитель в
следующем выражении:
i = 100 / i;
Очевидно, что при вводе нулевого значения
должно произойти исключение. При этом управление
будет передано блоку catch, а затем блоку finally.
В том случае, когда деление произошло успешно,
результат записывается в выходной поток и
выводится на консоль:
os.writeBytes(i + " ");
System.out.println(i + " ");
Назад Вперед |