Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Как привильно использовать Exception?


Автор: KOp4iK 18.1.2007, 13:05
Добрый день!

Вот задался мыслью повышать свой expirience в программировании. Хочется узнавать новое... учиться, учиться и ещё раз учиться. 

В данный момент есть мысль что весь мехинизм Exception'ов я использую процентов на 10... а то и меньше... тобишь просто так, где не попадя, вставлять
Код

try {

} catch (Exception e) {
     e.printstackTrace();
}
 
не есть гут. И вообще что правильно сделать окружить try-catch'ем или добавить в описание метода Exception?

Но вот как правильно что-то самому придумать неудаётся... да и есть мысль что "всё уже придумано до нас".

Мож кто в крадце опишет как ПРАВИЛЬНО делать или даст ссылку на большую и умную статью  smile 

Автор: w1nd 18.1.2007, 13:17
Всё предельно просто: если в данном коде вы можете обработать исключение - обрабатываете, не можете обработать - выбрасываете на уровень выше. Разумеется, 
Код
catch (Exception e) {
     e.printstackTrace();
}
 не есть обработка.

Автор: Vasay 18.1.2007, 13:55
Я думаю, все зависит от эксепшена, и в каждом случае надо писать свой обработчик.

Например, получил ты такой эксепшен - java.net.SocketTimeoutException, можно попробовать обратится скажем еще 2 раза (или в конфиге прописать, сколько попыток обращения нужно делать), и получив тоже самое сказать: "данный ресурс не доступен в данное время"

Автор: val 18.1.2007, 14:26
Если возникает экзепшин, то необходимо сразу же устранить его причины и убрать последствия, а если это невозможно, то про это надо сказать пользователю, немного перефразировав конечно, и закрыть программу...  smile  Типичное отражение экзепшина - это error message box в приложении. 

Автор: Vasay 18.1.2007, 14:33
Цитата(val @ 18.1.2007,  14:26)
Если возникает экзепшин, то необходимо сразу же устранить его причины и убрать последствия, а если это невозможно, то про это надо сказать пользователю, немного перефразировав конечно, и закрыть программу...  smile  Типичное отражение экзепшина - это error message box в приложении.

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

Автор: LSD 18.1.2007, 15:04
Цитата(Vasay @  18.1.2007,  14:33 Найти цитируемый пост)
Зачем сразу закрывать? Например, обращаешься к файлу, который на сетевом диске, а сетевой диск уже не доступен, будешь программу закрывать, или предложишь пользователю выбрать другой диск?

Значит надо показать пользователю сообщение об ошибке, и предложить выбор долбиться дальше или прекратить попытки.

Автор: chief39 18.1.2007, 17:31
Цитата(KOp4iK @  18.1.2007,  13:05 Найти цитируемый пост)
И вообще что правильно сделать окружить try-catch'ем или добавить в описание метода Exception?

Но вот как правильно что-то самому придумать неудаётся... да и есть мысль что "всё уже придумано до нас".

Мож кто в крадце опишет как ПРАВИЛЬНО делать или даст ссылку на большую и умную статью  smile

У тебя подход чуть не такой.
Эксепшн - это не цель, это средство.

Вот что ты будешь делать, если пришёл в магазин, а он закрыт?
Придумал?
Пойдёшь в другой?
Застрелишься от огорчения?
Вернёшься домой и скажешь маме/жене/дочке - "хлеба нет. магазин закрыт" ?

Придумал?

А теперь опиши этот алгоритм, только закрытость магазина расценивай как что-то из ряда вон выходящее, исключение. Джава просто предоставляет возможность с этим работать легко.

В методе покупкаХлеба() произошло исключение когда он вызывал метод открытьДверьМагазина(). Вот и решай сам что дальше делать. Мы ведь не знаем бизнес-логики твоих приложений.
Можешь вызвать метод вернутьсяДомойНесолоноХлебавши() или сделать "retry". То есть вызвать метод покупкаХлеба() с другим магазином в качестве параметра.

То есть используй это там, где необходимо.

А твой вопрос звучит как "Купил вчера отвёртку. Крестообразная, с деревянной ручкой. Что бы такое открутить? Или лучше закрутить? Поделитесь опытом. Может есть что-то, что можно открутить.  Подскажите адрес и как проехать. " smile



Автор: Tony 18.1.2007, 17:38
Код

try{
}catch(Exception e){
    //для разработ4ика 
    e.printStackTrace();
    // показиваем для ползователя
   ....
   //действия (optional)
}

Автор: chief39 18.1.2007, 17:44
Цитата(w1nd @  18.1.2007,  13:17 Найти цитируемый пост)
 не есть обработка.

Почему? smile

Это, скорее всего, в конкретном случае логически неверная обработка, но иногда именно стэктрэйс с продолжением работы и нужен.

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

Автор: COVD 18.1.2007, 19:03
Когда разрабатываешь, то часто нет представления, какие исключения могут быть и как их обрабатывать. Поэтому приходится ставить обычное  e.printStackException(). Потом , когда более ясная картина будет, можно соптимизировать. 

Автор: KOp4iK 18.1.2007, 19:57
Цитата

А твой вопрос звучит как "Купил вчера отвёртку. Крестообразная, с деревянной ручкой. Что бы такое открутить? Или лучше закрутить? Поделитесь опытом. Может есть что-то, что можно открутить.  Подскажите адрес и как проехать. "

ДА ИМЕННО!!! "Всю жизнь шурупы молотком забиваю!!! Интуитивно догадываюсь, что есть такие отвёртки и даже есть у меня одна такая, но как крутить ума не приложу! Пробовал отвёрткой забивать шурупы, но как-то не получается smile"

В общем ясно что ничего не ястно  smile 

Ладно, пример из головы (первый попавшийся). 

Есть строчка типа String( smile ). Из этой строчки патаемся создать объект типа Human:
Код

public class Human {
    private String m_name;
    private int m_age;
    private float m_height;
}

В строчке эти данные через знак "точка с запятой (;)". Предполагаем что в имени человека нет знака "точка с запятой (;)" (хотя это мысль ... назвать ребёнка "%№:[!?};*)" ). 

Логично что в класе Human есть методы:
Код

    public void setName(String name) {
        m_name = name;
    }
    public void setAge(int age) {
        m_age = age;
    }
    public void setHeight(float height) {
        m_height = height;
    }

А мож их такими создать?
Код

    public void setName(String name) {
        m_name = name;
    }
    public void setAge(String age) {
        m_age = Integer.parseInt(age);
    }
    public void setHeight(String height) {
        m_height = Float.parseFloat(height);
    }

А может так? 
Код

    public void setName(String name) {
        if (name.length() == 0) {
            throw new IllegalArgumentException("to short name");
        }
        m_name = name;
    }
    public void setAge(String age) throws NumberFormatException {
        m_age = Integer.parseInt(age);
    }
    public void setHeight(String height) throws NumberFormatException{
        m_height = Float.parseFloat(height);
    }

ну и конечноже: Как должен выглядеть метод создания объекта Human? так?
Код

    public static Human createHumanFromString(String s) {
        Human human = null;
        try {
            StringTokenizer st = new StringTokenizer(s, ";");
            if (st.hasMoreTokens()) {
                human = new Human();
                human.setName(st.nextToken());
                if (st.hasMoreTokens()) {
                    human.setAge(st.nextToken());
                    if (st.hasMoreTokens()) {
                        human.setHeight(st.nextToken());
                        return human;
                    }
                }
            }
        } catch (NumberFormatException e) {
            // roblema s vozrastom ili rostom
            e.printStackTrace();  
        } catch (IllegalArgumentException e) {
            // problema s imenem
            e.printStackTrace();  
        }
        return human;
    }


Добавлено @ 19:59 
Ах да и ещё в догонку на сколько важно/нужно свои Exception'ы создавать? И если да то в каких местах?

Автор: chief39 18.1.2007, 22:15
Ну смотри... вот парсишь ты.

И говоришь - "что делать с эксепшном?"

А когда где и зачем ты парсишь?
И что бы ты сделал, если бы сам, ручками, вместо компа, разбирал и что-то не сошлось?

Вот пока ты сам не знаешь что ты хочешь делать если так не выйдет - тогда кто тебе посоветует что сделать?

Если тебе на это пофик - можешь блоки catch пустыми оставить
Если это юзер на форме неправильно ввёл что-то - можешь вывести надпись: "#$@#$@!!!! %$#%%$~!!!! %$^%$#%!!!! КОДА ВЫ НАКОНЕЦ-ТО ПРАВИЛЬНО ЗАПОЛНИТЕ ПОЛЯ???".
Или: "в данном поле необходимо вводить число"
Если тебе по сети прислали такой объект - тогда можешь остановить выполнение программы(дальнейшую обработку).
Или сообщить, приостановить записать в лог ошибку, вывести надпись куда сможешь.

Смотря что тебе требуется от программы.

Вот что делал бы дворник дядя Коля если бы сломала метла? Не знаешь? А почему спрашиваешь что должна делать программа? То же, что и дядя Коля!

Вот если ты расскажешь что дядя Коля должен пожаловаться начальнику или деньги заплатить - тогда - прекрасно - можно в программе реализовать отправку сообщения и перечисление денег.

Понимаешь к чему я веду? smile

К тому, что ты сам опиши клиентскую логику работы программы, чотб она понимала что от неё требуется smile
Вот TCP пакет потерял - заново будет пересылать пока всё ок не станет. UDP потерял? - пофиг! Вот как тут можно сказать кто из них правильно работает? Что требуют то и делают smile

Вот в твоём случе я бросал бы собственный InvalidDataException, а правильно или нет - хрен его знает  - я не в курсе требований к твоей системе(а с них любая работа начинается).
А не "копайте тут и тут, а я пока узнаю где надо"


Вообще, эксепшн - это порсто сообщение. что что-то не так. Его можно создать и выбросить(то есть сообщить "у меня тут лажа").
Тот кто тебя послал делать то, что вызвало эксепшн, то есть вызвавший тебя метод должен 
  • или сказать "а я и сам хрен его знает.." и попросить вышестоящее руководство разобраться(то есть перебросить наверх)
  • или поймать эксепшн и разобраться с проблемой(сообщить кому-то(лог или месседж), попросить переделать кого-то(переустановить коннекш), смириться(пусотй блок обработки) )
  • ещё можно поймать эксепшн и выбросить наверх уже своего типа(по принципу - водитель видит что "карбюратор засорился" и сообщает начальнику "поломался, ехать не могу")
Цитата(KOp4iK @  18.1.2007,  19:57 Найти цитируемый пост)
Ах да и ещё в догонку на сколько важно/нужно свои Exception'ы создавать? И если да то в каких местах? 

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

См. пример с водилой. Свои эксепшны: КарбюраторЗасорился и МашинаСломалась



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






Автор: RebornCrusader 19.1.2007, 02:31
Где-то прочитал хорошую фразу: ловите эксепшены как можно раньше (на более низком уровне); решайте, как поступить - на как можно более высоком уровне.
А чисто на пальцах: на одни проблемы подчинённых начальнику начихать, от других - у начальника возникают свои собственные.

И следует помнить, что выброс исключения (не отлов, а именно ситуация возникновения) кушает относительно много ресурсов.
Что касается конкретьной реализщации, я бы сказал, это от собственного стиля зависит.

Вообще, всё это описано в любой толковой книжке в соответствующей главе.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)