
- •Лабораторная работа № 4 Работа с исключениями и коллекциями
- •Исключения в Java. Теоретические сведения
- •Использование try, catch и throw
- •Использование множественного catch и finally
- •Использование ключевого слова throws
- •Системные исключения
- •UnsupportedOperationException - обнаружена неподдерживаемая операция Коллекции (перечислимые типы) в Java. Теоретические сведения.
- •Иерархия интерфейсов коллекций
- •Назначение интерфейсов, расширяющих интерфейс Collection
- •Рабочие классы интерфейса List
- •Массив типа ArrayList
- •Методы класса ArrayList
- •Массив типа LinkedList
- •Методы класса LinkedList
- •Ассоциативные массивы в Java
- •Диаграмма интерфейса Map
- •Рабочие классы интерфейса Map
- •Задание
- •Приложение 1. Работа с датой и временем в Java
- •Приложение 2. Пример общего класса обработки ошибок, сообщений и логирования.
Использование множественного catch и finally
В предыдущем примере было представлено исключение, вызываемое вручную. Однако, многие исключения могут возникать автоматически в процессе выполнения программы. В том числе несколько исключений, как вызванных вручную, так и созданных автоматически могут возникнуть внутри одного блока try. Поэтому конструкция catсh – допускает множественное применение, чтобы обработать все исключения, возникающие в блоке try.
Пример. Использование множественного catch и finally в программе «Hallo Java»
try {
float test = str.length()/str.length();
if( str.equals("") ) { //Или можно использовать метод str.isEmpty() throw new java.io.IOException("Введена пустая строка"); //Никакой оператор в блоке try после throw не будет выполнен } System.out.println ("Спасибо, что ввели данные!\n"); } catch( java.io.IOException exc) { System.err.println ("Вызвано исключение \""+exc.getMessage()+"\"!\n" ); } catch( ArithmeticException exc) { System.err.println ("Вызвано исключение \""+exc.getMessage()+"\"!\n" ); } finally { //Вызывается непосредственно перед выходом из любого блока try-catch System.out.println ("Будет напечатано всегда" ); } |
Пояснения к примеру
Если строка str – пуста, то str.length = 0 и операция деления на 0 вызовет автоматически генерируемое исключение ArithmeticException. Управление будет передано блоку catch, обрабатывающий данный тип исключений. В результате будет напечатано - Вызвано исключение "/ by zero"!.
Ключевое слово finally создаёт блок кода, который будет выполнен после завершения блока try/catch, но перед кодом, следующим за ним. Блок будет выполнен, независимо от того, передано исключение или нет. Оператор finally не обязателен, однако каждый оператор try требует наличия либо catch, либо finally. Причина введения ключевого слова finally в том, что когда выполнение передается в блок catch, при этом в блок try могут остаться «открытые ресурсы». Например, при входе в try открываетcя файл и закрывает при выходе. Чтобы закрытие файла не было пропущено из-за обработки исключения, используется механизм finally.
Для немедленного вывода сообщений об ошибках используется небуферизированный поток вывода System.err.
Использование ключевого слова throws
Ключевое слово throws используется в методах классов для передачи исключений в вызывающий код, если сам метод не обрабатывает эти исключения.
Рассмотрим пример. Пусть некоторый код сохраняет данные из списка объектов книг (класс Book) в файлы так, что данные одной книги записываются строго в один файл. Этот код можно определить как метод saveToFile(String FileName) класса Book.
Пример. Метод saveToFile класса Book
public class book {
...
/** * Добавляем поля объекта в файл * @param FileName имя файла с путем * @param Update: true или false */ public void saveToFile(String FileName, boolean Update) {
try{ FileWriter dataOut = new FileWriter(FileName, Update); dataOut.append(this.toString()); dataOut.close(); } catch( IOException exc ) { System.err.println(exc.getMessage()); }
}
...
} |
Предположим теперь, что мы создаем класс Books для хранения списка книг и определяем в нем метод saveAllToFile(String FileName) для записи всех книг из списка в файлы и хотим знать количество успешных операций записи. Тогда ошибку записи из метода saveToFile надо передать в метод saveAllToFile, перехватить там и инкрементировтаь счетчик ошибок записи.
Изменим код метода saveToFile объявив, что данный метод может генерировать исключение.
Пример. Метод saveToFile класса Book
public void saveToFile(String FileName, boolean Update) throws java.io.IOException { //Сообщаем, что метод может вернуть исключение try{ FileWriter dataOut = new FileWriter(FileName, Update); dataOut.append(this.toString()); dataOut.close(); Result = true; } catch( IOException exc ) { System.err.println(exc.getMessage()); throw new java.io.IOException("Не удалось записать файл"+FileName); //Передаем исключение после печати сообщения о нем } } |
Теперь в методе saveAllToFile класса Books можно перехватить исключение, возвращаемое методом saveToFile класса Book и инкрементировать счетчик ошибок ErrCounter.
Пример. Метод saveAllToFile класса Books
public class Books extends java.util.HashMap<Integer, book> { //Объявляем класс Books наследником ассоциативного массива HashMap ... /** * Записываем все сгенеренные данные в файл * @param FileName * @return boolean */ public boolean saveAllToFile(String FileName) { boolean Result = true; int ErrCounter = 0; book tempBook;
for (Map.Entry<Integer, book> entry : this.entrySet()) { //выполняем проход по элементам объекта Books, «спрятанного» в this tempBook = entry.getValue(); try { tempBook.saveToFile(FileName, true); //Выполнение этого метода может вызвать исключение } catch (IOException exc) { Result = false; System.err.println(exc.getMessage()); ErrCounter++; } } return Result; } ...
} |