Почему надо обязательно использовать Try - catch

204
23 декабря 2019, 10:00

Есть программа на Java в которой допустим (к примеру) есть функция отображение списка категорий, который берется из базы данных через mysql запрос. Есть отдельная функция подключения к этой базе данных которая используется во всех функция - под названием Podkliucenije();

Вопрос: Почему надо использовать try - catch в самих функциях где уже есть вызов функции подключения и почему без него выдает кучу ошибок, а с ним все работает?

Функция подключения

Statement stmt;
Connection conn;
public void Podkliucenije()
    {
        // Podkliucenije k baze dannix
        try
        {
            Class.forName("org.apache.derby.jdbc.ClientDriver");
            String DB_URL = "jdbc:derby://localhost/db";
            String USER = "pavel";
            String PASS = "password";
            kategorijos.clear();
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            stmt = conn.createStatement();
            System.out.println("Podkliucheno");
        }
        catch (Exception e)
        {
            System.out.println("Osibka podkliucenija k DB");
            e.printStackTrace();
        }
    }

Пример одной из функции использования

public ArrayList<Kategoriji> polucitSpisokKategorij()
    {
        try
        {
            Podkliucenije();
            String sql = "SELECT * FROM kategoriji";
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next())
            {
                String nazvanije = rs.getString(1);
                String opisanije = rs.getString("opisanije");
                System.out.println(nazvanije + " - " + opisanije);
                kategorijos.add(new Kategoriji(nazvanije, opisanije));
            }
            rs.close();
            stmt.close();
            conn.close();
        }
        catch (Exception e)
        {
            System.out.println("Osibka podkliucenija k DB");
            e.printStackTrace();
        }
        return kategorijos;
    }
Answer 1

Почему надо обязательно использовать Try - catch

Использовать try-catch необязательно. При вызове небезопасного метода у Вас всегда есть выбор:

  • обернуть вызов опасного метода в try-catch
  • пометить свой метод throws SomeException (иногда данная опция недоступна при переопределении методов или имплементации интерфейсов)

Более того, в Java есть исключения, которые необязательно перехватывать(на этом остановимся чуть позже).

Exception является наследником класса Throwable, классом описывающим все исключительные ситуации. Вместе с Exception данный класс наследует класс Error.

  • Error используется в ситуации, когда восстановление работы программы не представляется возможным. Такие исключительные ситуации генерируются самой JVM. Например: OutOfMemeryError(нехватка памяти), StackOverflowError(переполнение стека), ThreadDeadError(смерть потока), VirtualMachineError(Ошибка виртуальной машины)

  • Exception же используется в ситуации, когда работу программы можно восстановить и продолжить.

Иерархия Throwable выглядит следующим образом:

              Throwable
              /      \
          Error     Exception
                        |
                RuntimeException

Throwable бывает двух типов:

  • checked ( проверяемые ) Данные исключения необходимо перехватывать, либо эскалировать исключение выше помечая свой метод throws Exception Пример: IOException, SQLException, etc.
  • unchecked ( непроверяемые ) Данные ситуации необязательно перехватывать и описывать в сигнатуре метода Пример: NullPointerException, IndexOutOfBoundsException, etc Также к unchecked относятся все ошибки(Error)

В чём смысл

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

Для этого вызывают примерно такой код:

throw new SomeException("У меня возникла проблема, которую я не могу решить!");

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

Для этого в сигнатуру метода добавляется:

public void myMethod() throws SomeException{
    //...
    throw new SomeException("У меня возникла проблема, которую я не могу решить!");
    //...
}

После этого все будут знать, что после того как они вызовут Ваш метод - они могут получить Exception в лицо. "Знание - сила!"...а еще можно сказать "Предупреждён, значит вооружен!".

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

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

Что происходит при выбросе исключения?

  1. При выбросе исключения работа программы прерывается.
  2. JVM идёт обратно(снизу вверх) по стеку выполнения.
    • Если в данном стеке встречается точка, в которой данное исключение перехватывается, то JVM передаёт управление в данную точку.
    • Если в стеке никто не перехватил данное исключение, то работа заканчивается и в стандартный поток вывода выводится информация о произошедшем.

В чём профит

Помимо прерывания работы и возможности передачи управления в другую точку программы (за что эксепшены часто критикуются) они несут еще и очевидный информативный характер.

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

Во-вторых: Как ни странно, но за стектрейс Вы также должны быть благодарны Throwable. Именно в момент создания Throwable сохраняется снимок стека выполнения текущего потока.

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

READ ALSO
Retrofit null response и call

Retrofit null response и call

Всем привет, проблема связанна не знаю сам с чем, пытался сделать супер-легкое приложение с retrofit 2 на андроиде и столкнулся с проблемой что...

251
Что используется в java для выявления багов

Что используется в java для выявления багов

Подскажите пожалуйста для тестирования в c# используется DebugLog()И Console

197
Уведомления на значках андроид

Уведомления на значках андроид

Уведомления на значках программы, как они работают и как это можно реализовать?

199
Тесты для функции

Тесты для функции

Есть функция для работы с переменной (полем) “Возраст студента”КАК спроектировать для этой функции любые кейсы (тесты) для верификации?

227