Читайте также:
|
|
Если метод способен к порождению исключения, которое он не обрабатывает, он должен определить свое поведение так, чтобы вызывающие методы могли сами предохранять себя от данного исключения. Это обеспечивается включением предложения throws в заголовок объявления метода. Предложение throws перечисляет типы исключений, которые метод может выбрасывать. Это необходимо для всех исключений, кроме исключений типа Error, RuntimeException или любых их подклассов. Все другие исключения, которые метод может выбрасывать, должны быть объявлены в предложении throws. Если данное условие не соблюдено, то произойдет ошибка времени компиляции. Общая форма объявления метода, которое включает предложение throws:
type method-name{parameter-list) throw exception-list
{
// тело метода
}
Здесь exception-list — список разделенных запятыми исключений, которые метод может выбрасывать.
Ниже показан пример неправильной программы, пытающейся выбросить исключение, которое она не перехватывает. Поскольку программа не определяет предложение throws, чтобы объявить этот факт, программа не будет компилироваться.
// Эта программа содержит ошибку и не будет компилироваться.
class ThrowsDemo {
static void throwOne() {
System.out.println("Внутри throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
throwOne();
}
}
Чтобы сделать этот пример компилируемым, требуется внести два изменения. Во-первых, нужно объявить, что throwOne() выбрасывает исключение IllegalAccessException. Во-вторых, main() должен определить оператор try/catch, который захватывает исключение. Исправленный пример выглядит так:
// Теперь эта программа корректна.
class ThrowsDemo {
static void throwOne() throws IllegalAccessException {
System. out. println("Внутри throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwOne ();
} catch (IllegalAccessException e) {
System. out. println("Выброс " + e);
}
}
}
Вывод, сгенерированный выполнением этой программы:
Внутри throwOne.
Выброс Java.lang.IllegalAccessException: demo
Метод должен объявлять все контролируемые исключительные ситуации, которые он может возбудить. Неконтролируемые исключительные ситуации либо находятся вне вашей компетенции (класс Error), либо являются следствием ваших логических ошибок, которые не следовало допускать (класс RuntimeException).
Если ваш метод не сообщает обо всех контролируемых исключительных ситуациях, компилятор выдаст сообщение об ошибке.
Вместо объявления исключительных ситуаций можно их перехватывать. В этом случае исключительная ситуация не возбуждается, и спецификация throws не нужна.
Рассмотрим пример:
Приведенный ниже метод может вызвать исключение связанное с ошибкой ввода/вывода. (FileNotFoundException)
import java.io.*;
public class TExceptWO {
public static void read(String filename) {
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read())!=-1)
{
// Обработка
}
}
public static void main(String args[]) {
String file = "a.b";
read (file);
}
}
В таком виде файл не будет компилироваться
В связи с этим возможны два варианта действий. Первый – использование спецификации throws (см. ниже)
import java.io.*;
public class TExсeptThrows {
public static void read(String filename) throws IOException {
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read())!=-1)
{
// Обработка
}
}
public static void main(String args[]) {
String file = "a.b";
try {
read (file);
} catch (IOException e1) {
System. out. println("Захват в вызывающем методе: " + e1);
}
}
}
Или
import java.io.*;
public class TExcept {
public static void read(String filename) {
Try
{
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read())!=-1)
{
// Обработка
}
}
catch (IOException exception)
{
exception.printStackTrace();
System. out. println(exception.getMessage());
}
}
public static void main(String args[]) {
String file = "a.b";
TExcept. read (file);
}
}
Компилятор строго следит за спецификаторами throws. Вызывая метод, возбуждающий контролируемую исключительную ситуацию, нужно либо самому обрабатывать ее, либо передавать на обработку другому методу. Как правило, следует перехватывать лишь те исключительные ситуации, которые вы сами можете обработать, а остальные передавать дальше. Передавая исключительную ситуацию, нужно добавлять спецификатор throws, чтобы предупредить вызывающий метод.
Обратите внимание на методы, которые могут возбуждать исключительные ситуации. Затем примите решение, обрабатывать исключительную ситуацию или включить в список throws. Во втором варианте нет ничего постыдного - лучше предоставить обработку исключительной ситуации более компетентному обработчику.
Учтите, пожалуйста, что у этого правила есть одно исключение. Если вы создаете метод, который замещает метод суперкласса, не возбуждающий ни одной исключительной ситуации, вы обязаны сами перехватывать каждую проверяемую исключительную ситуацию в коде метода. В такой метод подкласса нельзя добавить спецификатор throws, отсутствующий в методе суперкласса.
Не бойтесь возбуждать или передавать исключительные ситуации для проблем, которые вы не можете решить. С другой стороны, ваши товарищи-программисты возненавидят вас за то, что вы создаете методы, которые перекладывают обработку исключительных ситуаций на их плечи.
Дата добавления: 2015-07-19; просмотров: 63 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Оператор throw | | | Блок finally |