Создание исключения, не определенного в интерфейсе - PullRequest
16 голосов
/ 03 августа 2009

Какую рекомендацию следует придерживаться, когда вам нужно создать исключение, которое не было определено в интерфейсе, который вы реализуете?

Вот пример:

public interface Reader
{
    public abstract void read() throws IOException;
}

public class CarrotReader implements Reader
{
    public void read() throws IOException {}
}

public class CupcakeReader implements Reader
{
    public void read() throws IOException, CupcakeException {}
}

В этом случае у вас есть конкретное исключение, которое возникает при чтении кексов, поэтому вы хотите создать исключение, связанное с этим. Однако Reader не определяет этот тип исключения в своем интерфейсе, так что вы делаете? Кроме того, нет смысла добавлять CupcakeException к предложению throws в интерфейсе Reader , поскольку этот тип исключения относится только к CupcakeReader . Одним из способов решения этой проблемы является Reader определение read таким образом, чтобы он выбрасывал некоторый родительский тип, например Exception , но тогда вы теряете контекст для исключения. Что вы должны сделать в этой ситуации? Спасибо!


Другая интересная ситуация, которая возникла, связана с интерфейсом, который вы не можете контролировать. Как лучше всего указать, что в этом случае возникла проблема?

Для иллюстрации приведу еще один пример:

public interface Reader
{
    public abstract void read();
}

public class CupcakeReader implements Reader
{
    public void read() throws CupcakeException {}
}

В этом случае вы не можете изменить Reader , но хотите указать, что возникла проблема в CupcakeReader read method.

Ответы [ 6 ]

13 голосов
/ 03 августа 2009

Возможно, вам придется создать исключение ожидаемого типа.

... catch(CupcakeException e) {
   throw new IOException("The sky is falling", e);
 }
9 голосов
/ 03 августа 2009

Используйте нечто, называемое ReaderException, которое будет служить корневым интерфейсом вашей иерархии исключений. ReaderException также предоставляет ссылку на другие исключения, возникающие из-за исключений более низкого уровня.

2 голосов
/ 04 августа 2009

Исключение является частью интерфейса. Определите универсального родителя для всех ваших исключений в интерфейсе, если вы можете переопределить интерфейс.

Вы также можете сделать CupcakeException дочерним элементом IOException.

1 голос
/ 03 августа 2009

Только не используйте проверенные исключения.

Пример, который вы показали, является одной из причин, по которым проверенные исключения являются ошибочными.

Основная причина в том, что пользователь вашего устройства для чтения кексов должен будет обработать ваше исключение независимо от того, заинтересован он в этом или нет.

Так что вместо:

Value value = reader.read();

Вы заставляете его сделать это:

Value value = null;
try {
    value = reader.read();
} catch (Exception e) {
    // now what??
}

value.doSomething();   // potential NPE here

Подумайте, какой из них лучше, удобочитаемее и менее подвержен ошибкам, и просто перестаньте использовать проверенные исключения.

EDIT:

Я удивлен отрицательным рейтингом. Есть люди, которые до сих пор считают, что проверенные исключения - это здорово? Если это так, вот несколько ссылок, почему вы не должны использовать проверенные исключения:

  • Ни одна современная платформа не использует проверенные исключения (Spring, EJB3 и т. Д.)
  • Статья с примерами кода здесь
  • StackOverflow тема
  • Эффективная Java (разделы 58 и 59) - здесь
0 голосов
/ 03 августа 2009

Если вы создаете абстрактное исключение более высокого уровня, которое работает в качестве базового класса для CupCakeException, вы не привязываете интерфейс Reader к конкретной реализации, как это было бы, если бы вы добавили CupCakeException в интерфейс Reader. Если вы не позволяете одному исключению наследовать от другого, в классе исключений будет конструктор , который в качестве второго аргумента принимает метод throwable, такой как Thorbjørn Ravn Andersen, уже показанный в его примере короткого кода. Позволяет генерировать более абстрактное исключение, и каждая часть вашего кода, которая должна знать больше, чем просто «существует ошибка», может искать причину более высокого исключения.

0 голосов
/ 03 августа 2009

Возможно, вы могли бы создать абстрактный класс ReaderSpecificException, поместить его в интерфейс и подкласс CupcakeException из этого абстрактного класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...