Обработка исключений Java, выданных слушателями - PullRequest
4 голосов
/ 26 августа 2011

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

Теперь при использовании слушателей есть вероятность, что слушатель сделает что-то не так, что приведет к исключениюброшенный в объект библиотеки.

Пример

public interface SomeListener {
    public void progressNotification(int status);
}

public class SomeClass {
    SomeListener listener = null;
    …
    public void setListener(SomeListener listener) {
        this.listener = listener;
    }
    …
    public void someRandomMethod() {

        int progressStatus = 0;
        //Do some stuff here that updates progressStatus

        //then notify the caller
        if (listener != null) {
            listener.progressNotification(progressStatus);
        } 
    }
}

public class CallerClass implements SomeListener{
    public void progressNotification(int status) {
        //do something that will throw an exception 
        //e.g assume status is 0
        int x = 200/status; //this will throw an ArithmeticException because of division by zero
    }
}

Если SomeClass не перехватит исключение и не обработает его, это приведет к тому, что любой код после listener.progressNotification(progressStatus); не будет выполненоставив объект в «неправильном» состоянии.

Итак, мой вопрос: как лучше всего справиться с такого рода исключениями в библиотеке?

Я видел одну библиотеку, которая делаетэто:

    if (listener != null) {
        try {
            listener.progressNotification(progressStatus);
        }catch (Thrwowable th) {
            System.err.println("An uncaught throwable " + th);
        }
    } 

, что мне не подходит.

Ответы [ 3 ]

7 голосов
/ 26 августа 2011

Для меня контракт слушателя должен быть четко определен:

  • он должен быстро возвращаться (т. Е. Не останавливать или не спать поток и т. Д.),
  • не должен выбрасывать какие-либо исключения во время выполнения.

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

Я бы не стал делать ничего, кроме четкого определения и документирования договора и объяснения потенциального воздействия разрыва договора (т.е. недетерминированного состояния, что угодно).Если клиент действительно хочет защитить себя от программной ошибки, он все равно может обернуть весь код слушателя в try / catch, как показывает ваш пример.

2 голосов
/ 26 августа 2011

То же самое для всех, мы ничего не можем сделать для RuntimeException.И именно поэтому они отмечены непроверенным исключением. Здесь - хорошее прочтение о непроверенном исключении.

Оно четко определяет это:

Исключения во время выполнения могут возникать где угодно в программе, и в типичномможет быть очень многочисленным. Необходимость добавления исключений времени выполнения в каждое объявление метода уменьшит ясность программы .Таким образом, компилятор не требует, чтобы вы перехватывали или указывали исключения времени выполнения (хотя вы можете).

Так что об этом не нужно беспокоиться.

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

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

1 голос
/ 26 августа 2011

Если вы не хотите, чтобы слушатель с плохим поведением останавливал все уведомления для всех, тогда вам необходимо выполнить такую ​​обработку исключений.У меня есть некоторые кусачки.Конечно, я бы записал это вместо записи в stderr.И ловить Throwable не очень хорошо, есть некоторые вещи (из-за ошибок памяти, с одной стороны), которые вы могли бы так же отпустить.Но основная идея в порядке.

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