Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Хорошо или плохо пробрасывать не проверяемые, исключения вместо проверяемых 
V
    Опции темы
Royan
  Дата 14.4.2008, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Представим, что у нас есть интерфейс:

Код

interface IFoo {
        public String[] readStrings();


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

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

Код

try {
    stream.readLong(); // типа что-то читаем
} catch (IOException e) {
    throw new IllegalStateException("IO exception occurred. Details: " + e.getMessage());
}


Вопрос хорошо так поступать или плохо? Есть какие-нибудь советы по этому поводу?


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
Kangaroo
Дата 14.4.2008, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 21
Всего: 104



Цитата(Royan @  14.4.2008,  17:34 Найти цитируемый пост)
Вопрос хорошо так поступать или плохо? Есть какие-нибудь советы по этому поводу? 

Вообще-то плохо. Если разработчик интерфейса решил, что readStrings() должен сам разбираться с исключительными ситуациями, значит так и должно быть.


--------------------
Lost....
PM MAIL MSN   Вверх
Royan
Дата 14.4.2008, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Цитата(Kangaroo @  14.4.2008,  14:48 Найти цитируемый пост)
сли разработчик интерфейса решил, что readStrings() должен сам разбираться с исключительными ситуациями

Разработчик не бог, может быть и дураком.


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
LSD
Дата 14.4.2008, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Royan @  14.4.2008,  18:34 Найти цитируемый пост)
Вопрос хорошо так поступать или плохо? Есть какие-нибудь советы по этому поводу?

Все зависит от контракта метода readStrings(), по хорошему даже RuntimeException надо декларировать.

Смысл RuntimeException состоит в том, что их можно избежать если провести проверку входных данных.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Royan
Дата 14.4.2008, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



LSD, Я чисто из безграмотности хочу спросить, который раз уже встречаю выражение "контракт", что под этим имеется ввиду? Что такое контракт метода?


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
LSD
Дата 15.4.2008, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Контракт метода, это описание его поведения. Какие аргументы он принимает, какие у них могут быть значения, что он делает в зависимости от тех или иных условий, что возвращает и т.д.

Возьмем для примера Iterator.remove(), там описывается, что этот метод делает, как меняется состояние коллекции, в каких случаях возможны эксепшены. Обрати внимаение, хотя оба эксепшера runtime, но тем не менее они описаны в контракте интерфейса. И значит любой кто будет реализовывать этот интерфейс, должен его соблюдать.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Royan
Дата 18.4.2008, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



LSD, Спасибо!


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
Stampede
Дата 19.4.2008, 02:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 24
Всего: 144



Royan, вопросы правомерные, и развернуый ответ на них может потянуть на хорошую монографию. Но я постараюсь все же покороче smile

Сначала быстрый ответ: да, в ситуации, которую ты обрисовал, оборачивать в нечекнутое и пробрасывать наверх - это нормальное решение.

Теперь немного поподробнее. Как бы мы ни стремились к идеалу, но жизнь есть жизнь, и зачастую приходится работать с тем что есть. Например, с некими API'ями, над которыми мы не властны. Вот у нас есть интерфейс с методом readStrings, который не объявляет никаких исключений. А нам надо писать его имплементацию. И мы точно знаем, что нам предстоит иметь дело с методами, которые выбрасывают IOException. И что нам остается делать? А ничего другого - только оборачивать в один из типов RuntimeException и пробрасывать в таком виде. Ну не глотать же его, в самом деле - уж это-то точно будет самым никудышным вариантом.

Пуристы могут возразить: но ведь тем самым мы нарушаем контракт! Ведь автор API'я такого не предусматривал?

Спокойно, бабуся - ответим мы. Что значит не предусматривал? Вообще, какие у автора могли быть выборы? Ну, допустим, объявить некое общее чекнутое исключение типа IOException. Было ли бы это как-то полезно юзерам либы? Парадоксальный ответ - НЕТ!

Как показывает практика, и к чему приходят наиболее продвинутые Java-мыслители, чрезмерное увлечение чекнутыми исключениями только засирает API и провоцирует разработчиков фактически игнорировать их, используя универсальные уловители и обобщенные объявления.

Вот допустим у нас есть метод, который инстанциирует класс по имени: Class.forName(someName).newInstance().

Какими только чекнутыми исключениями нас не пугают в этой короткой записи! И ввод-вывод, и безопасность, и классовая непоноценность. Но есть ли нам какое-то дело до того, почему у нас не создался объект? Можем ли мы в этот момент что-то поправить? Практически никогда! Но метод, внутри которого происходит все это безобразие, должен что-то делать с той дюжиной исключений, которые могут вылетать из его потрохов. Неужели выносить все эти объявления в сигнатуру метода? Но там, откуда это вызывается, тем более понятия не имеют, как реагировать на IllegalAccessException! Поэтому разработчик сделает одно из двух:

Код

public Transglucator create(String className) throws Exception {
    // ...
    Object obj = Class.forName(className).newInstance();
    return (Transglucator) obj;
}


или

Код

public Transglucator create(String className) {
    {
        // ...
        Object obj = Class.forName(className).newInstance();
        return (Transglucator) obj;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}


В английском это называется "defeat the purpose", что в волном переводе звучит как "за что боролись, на то и напоролись".

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

Взять хоть тот же метод Iterator.remove(). Разве не может в какой-нибудь из его (потенциально бесчисленных) реализаций вылететь на рантайме какой-нибудь ArrayOutOfBoundsException или NullPointerException? Да запросто! И хоть разработчик, использующий итератор, должен держать в уме возможность получения официально объявленного IllegalStateException, не стоит забывать, что и другие рантаймные исключения также возможны - и соответственно структурировать свой код.

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

Примерно так поступает Род Джонсон в своем Спринге. И хоть фреймворк такого размаха не каждому по плечу, но отдельные здравые идеи оттуда не грех и позаимствовать для использования в своей практике.

Вот.





--------------------
"If you want something done right, do it yourself"
По секрету: выучить английский - реально!
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0991 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.