Java: руководство для начинающих (ЛП) - Шилдт Герберт
Шрифт:
Интервал:
Закладка:
Таблица 9.2. Непроверяемые исключения, определенные в пакете java.langИсключениеОписаниеArithmeticExceptionАрифметическая ошибка, например попытка деления на нульArraylndexOutOfBoundsExceptionПопытка обращения за границы массиваArrayStoreExceptionПопытка ввести в массив элемент, несовместимый с ним по типуClassCastExceptionНедопустимое приведение типовEnumConstNotPresentExceptionПопытка использования нумерованного значения, которое не было определено ранееIllegalArgumentExceptionНедопустимый параметр при вызове методаIllegalMonitorStateExceptionНедопустимая операция контроля, например, ожидание разблокировки потокаIllegalStateExceptionНедопустимое состояние среды выполнения или приложенияIllegalThreadStateExceptionЗапрашиваемая операция несовместима с текущим состоянием потокаIndexOutOfBoundsExceptionНедопустимое значение индексаNegativeArraySizeExceptionСоздание массива отрицательного размераNullPointerExceptionНедопустимое использование пустой ссылкиNumberFormatExceptionНеверное преобразование символьной строки в числоSecurityExceptionПопытка нарушить систему защитыStringlndexOutOfBoundsПопытка обращения к символьной строке за ее границамиTypeNotPresentExceptionНеизвестный типUnsupportedOperationExceptionНеподдерживаемая операция
Таблица 9.3. Проверяемые исключения, определенные в пакете java.langИсключениеОписаниеClassNotFoundExceptionКласс не найденCloneNotSupportedExceptionПопытка клонирования объекта, не реализующего интерфейс CloneableIllegalAccessExceptionДоступ к классу запрещенInstantiationExceptionПопытка создания объекта абстрактного класса или интер¬фейсаInterruptedExceptionПрерывание одного потока другимNoSuchFieldExceptionТребуемое поле не существуетNoSuchMethodExceptionТребуемый метод не существуетReflectiveOperationExceptionСуперкласс исключений, связанных с рефлексией (добавлен в версии JDK 7)Создание подклассов, производных от класса Exception
Несмотря на то что встроенные в Java исключения позволяют обрабатывать большинство ошибок, механизм обработки исключений не ограничивается только этими ошибками. В частности, можно создавать исключения для обработки потенциальных ошибок в прикладной программе. Создать исключение несложно. Для этого достаточно определить подкласс, производный от класса Exception, который, в свою очередь, является подклассом, порожденным классом Throwable. В создаваемый подкласс не обязательно включать реализацию каких-то методов. Сам факт существования такого подкласса позволяет использовать его в качестве исключения.
В классе Exception не определены новые методы. Он лишь наследует методы, предоставляемые классом Throwable. Таким образом, все исключения, включая и создаваемые вами, содержат методы класса Throwable. Конечно же, вы вольны переопределить в создаваемом вами классе один или несколько методов.
Ниже приведен пример, в котором создается исключение NonlntResultException. Оно генерируется в том случае, если результатом деления двух целых чисел является дробное число. В классе NonlntResultException содержатся два поля, предназначенные для хранения целых чисел, а также конструктор. В нем также переопределен метод toString (), что дает возможность выводить описание исключения с помощью метода println().// Применение специально создаваемого исключения.// создать исключениеclass NonlntResultException extends Exception { int n; int d; NonlntResultException(int i, int j) { n = i; d = j; } public String toString() { return "Result of " + n + " / " + d + " is non-integer."; }}class CustomExceptDemo { public static void main(String args[]) { // В массиве numer содержатся нечетные числа, int numer[] = { 4, 8, 15, 32, 64, 127, 256, 512 }; int denom[] = { 2, 0, 4, 4, 0, 8 }; for(int i=0; i<numer.length; i++) { try { if((numer[i]%2) != 0) throw new NonlntResultException(numer[i], denom[i]); System.out.println(numer[i] + " / " + denom[i] + 11 is " + numer[i]/denom[i]); } catch (ArithmeticException exc) { // перехватить исключение System.out.println("Can11 divide by Zero!"); } catch (ArraylndexOutOfBoundsException exc) { // перехватить исключение System.out.println("No matching element found."); } catch (NonlntResultException exc) { System.out.println(exc) ; } } }}
Результат выполнения данной программы выглядит следующим образом:4 / 2 is 2Can't divide by Zero!Result of 15 / 4 is non-integer.32 / 4 is 8Can't divide by Zero!Result of 127 / 8 is non-integer.No matching element found.No matching element found.
Пример для опробования 9.1.Добавление исключений в класс очереди
В этом проекте предстоит создать два класса исключении, которые будут использоваться классом очереди, разработанным в примере для опробования 8.1. Эти исключения должны указывать на переполнение и опустошение очереди, а генерировать их будут методы put () и get () соответственно. Ради простоты эти исключения добавляются в класс FixedQueue, но вы можете без труда внедрить их в любые другие классы очереди, разработанные в примере для опробования 8.1.
Последовательность действий
Создайте файл QExcDemo.java.
Определите следующие исключения в файле QExcDemo.java: /* Пример для опробования 9.1. Добавление обработчиков исключений в класс очереди. */ // Исключение, указывающее на переполнение очереди, class QueueFullException extends Exception { int size; QueueFullException(int s) { size = s; } public String toString() { return "nQueue is full. Maximum size is " + size; } } // Исключение, указывающее на опустошение очереди, class QueueEmptyException extends Exception { public String toString() { return "nQueue is empty."; } }
Исключение QueueFullException генерируется при попытке поместить элемент в уже заполненную очередь, а исключение QueueEmptyException — в ответ на попытку извлечь элемент из пустой очереди.
Измените класс FixedQueue таким образом, чтобы при возникновении ошибки он генерировал исключение. Соответствующий код приведен ниже. Введите этот код в файл QExcDemo.java.// Класс, реализующий очередь фиксированного размера// для хранения символов.class FixedQueue implements ICharQ { private char q[]; // Массив для хранения элементов очереди, private int putloc, getloc; // Индексы размещения и извлечения // элементов очереди. // создать пустую очередь заданного размера public FixedQueue(int size) { q = new char[size+1]; // выделить память для очереди putloc = getloc = 0; } // поместить символ в очередь public void put(char ch) throws QueueFullException { if(putloc==q.length-1) throw new QueueFullException(q.length-1); putloc++; q[putloc] = ch; } // извлечь символ из очереди public char get() throws QueueEmptyException { if(getloc == putloc) throw new QueueEmptyException(); getloc++; return q[getloc]; }}
Добавление исключений в класс FixedQueue выполняется в два этапа. Сначала в определении методов get () и put () указывается оператор throws с типом генерируемого исключения. А затем в этих методах организуется генерирование исключений при возникновении ошибок. Используя исключения, можно организовать обработку ошибок в вызывающей части программы наиболее рациональным способом. Как вы помните, в предыдущих версиях рассматриваемой здесь программы выводились только сообщения об ошибках. А генерирование исключений является более профессиональным подходом к разработке данной программы.
Для опробования усовершенствованного класса FixedQueue введите в файл QExcDemo.java приведенный ниже исходный код класса QExcDemo.// Демонстрация исключений при обращении с очередью,class QExcDemo { public static void main(String args[]) { FixedQueue q = new FixedQueue(10); char ch; int i; try { // Переполнение очереди. for(i=0; i < 11; i++) { System.out.print("Attempting to store : " + (char) ('A' + i)); q.put((char) (fA' + i)); System.out.println(" - OK"); } System.out.println(); } catch (QueueFullException exc) { System.out.println(exc); } System.out.println(); try { // Попытка извлечь символ из пустой очереди. for(i=0; i < 11; i++) { System.out.print("Getting next char: "); ch = q.get(); System.out.println(ch); } } catch (QueueEmptyException exc) { System.out.println(exc); } }}