Интерфейс Java не объявляет исключения. Как управлять контролируемыми исключительными ситуациями реализации?

Скажем, у меня есть следующий интерфейс Java, который я не могу изменить:

public interface MyInterface {
  public void doSomething();
}

И теперь класс, реализовывая его похож на это:

class MyImplementation implements MyInterface {
  public void doSomething() {
    try {
      // read file
    } catch (IOException e) {
      // what to do?
    }
  }
}

Я не могу восстановиться с не чтения файла.

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

Что я могу сделать?


Все мы соглашаемся: интерфейс является дефектным.

Решение я выбрал

Я наконец решил записать a MyVeryOwnInterface это расширяется MyInterface и добавляет как часть подписи дефектных методов MyRuntimeException:

public interface MyVeryOwnInterface extends MyInterface {
  public void doSomething() throws MyRuntimeException;
}
class MyImplementation implements MyVeryOwnInterface {
  public void doSomething() throws MyRuntimeException {
    try {
      // read file
    } catch (IOException e) {
      throw new MyRuntimeException("Could not read the file", e);
    }
  }
}
5
задан Olivier Grégoire 30 April 2010 в 12:48
поделиться

6 ответов

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

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

8
ответ дан 18 December 2019 в 13:12
поделиться

Если вы не можете восстановить, чем вы нужно выбросить и, таким образом, обернуть его в RuntimeException или Error и выбросить.

public class Unchecked extends Error {

   private final Exception source;

   public Unchecked( Exception source) {
       this.source = source;
   }

   public String toString() {
       return "Unchecked Exception, Caused by: " + source;
   }

   public Exception getSource() {
       return source;
   }

   public static Unchecked wrap( Exception cause ) {
       return new Unchecked(cause);
   }
}
2
ответ дан 18 December 2019 в 13:12
поделиться

Я бы бросил new IOError (e); и сообщил о проблеме разработчику интерфейса.

3
ответ дан 18 December 2019 в 13:12
поделиться

Очевидно, что разработчик интерфейса виноват в том, что не учел возможность отказа doSomething (). В идеале он должен был либо разрешить выброс IOException (если он подозревал, что будет задействован ввод-вывод), либо SomethingException (проверено), которое вы могли бы использовать для обертывания исключения IOException.

Если вам доступен дизайнер интерфейса, поговорите с ним и спросите, что они ожидают от вас в случае сбоя. Может быть, они могут изменить интерфейс: или, может быть, допустимо молча потерпеть неудачу в соответствии с контрактом интерфейса.

Если все это не удается, вы ограничиваетесь выбором: молчание (возможно, запись, но не реагирование на проблему) или выброс RuntimeException, который может завершить процесс.

1
ответ дан 18 December 2019 в 13:12
поделиться

Я бы посоветовал

throw new RuntimeException("while reading file " + fileName + "...", e);

Разве проблема не в том, что интерфейс вообще не ожидает каких-либо проблем?

(и вы можете создать свое собственное OurCompanyDomainException extends RuntimeException, чтобы его было легко различать в коде на другой стороне интерфейса) .

0
ответ дан 18 December 2019 в 13:12
поделиться

Я не думаю, что есть что-то делать, кроме как объявить бросает IOException в интерфейсе. Это это просто природа интерфейсов Java и проверенных исключений.

В вашем классе может быть другой метод ( doSomethingDangerous ), который генерирует исключение IOException . В реализации doSomething вы просто вызываете doSomethingDangerous (заключенный в try / catch), а затем, где бы вы ни пожелали, будьте осторожны с doSomething , вы вызываете doSomethingDangerous напрямую.

0
ответ дан 18 December 2019 в 13:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: