try-catch-finally выдает исключение в проблеме Java

Я новичок в Java, но я подумал, что при использовании try-catch-finally мне не нужно объявлять исключение с помощью throws SQLException. Однако, если я его не использую, компилятор выдает мне ошибку:

«несообщаемое исключение java.sql.SQLException; должно быть перехвачено или объявлено для выдачи».

Я включил улов, поэтому я не уверен, почему возникают эти ошибки.

public static ResultSet getResultSet ( String query ) 
{
    dbConn = getConnection();

    try
    {
       stmt = dbConn.createStatement( );

       ResultSet rs = stmt.executeQuery( query );

       return rs;
    }
   catch (SQLException ex)
   {
       return null;
   }
   finally
   {
       stmt.close();
       dbConn.close();
   }
}

person Mike55    schedule 11.08.2010    source источник
comment
Помогите, много котят умирает. Вы объявили dbConn и stmt как static. Этот код определенно не является потокобезопасным. Я настоятельно рекомендую переделать базовые руководства по Java и JDBC.   -  person BalusC    schedule 11.08.2010
comment
Вы также получите SQLExceptions при использовании ResultSet, так что вы можете распространить исключение. ResultSet, вероятно, не будет работать после закрытия соединения. Возможно, вы захотите рассмотреть идиому Execute Around. stackoverflow.com/questions/341971/   -  person Tom Hawtin - tackline    schedule 11.08.2010
comment
Серьезно, это хорошо в качестве эксперимента для обучения вашего собственного человека, но не размещайте это на реальном сервере, иначе все сломается, как только два человека будут использовать его одновременно. :(   -  person leoger    schedule 11.08.2010
comment
Большое спасибо за отличные комментарии   -  person Mike55    schedule 11.08.2010


Ответы (4)


Это потому, что методы close():

stmt.close();
dbConn.close();

может выдать SQLException, и вы не инкапсулировали их в блоке try/catch.

Метод вполне может генерировать исключение из предложения finally, и, поскольку предложение catch не обрабатывает эти исключения, метод должен быть объявлен так, чтобы генерировать эти исключения.

В принципе, вам нужно сделать что-то вроде

finally
{
    try {
        stmt.close();
    } catch (SQLException sqle) {
        // log the statement-close exception
    }

    try {
        dbConn.close();
    } catch (SQLException sqle) {
        // log the connection-close exception
    }
}
person aioobe    schedule 11.08.2010
comment
Нет, в основном вам нужно поместить каждый close() в собственный try-catch, который регистрирует или игнорирует исключение. В вашем примере, если stmt.close() выкинет, то dbConn.close() никогда не состоится. - person BalusC; 11.08.2010
comment
Вы также можете добавить nullchecks. - person BalusC; 11.08.2010

Поместите dbConn = getConnection(); в раздел try. Это тоже может бросить SQLException.

person Adam    schedule 11.08.2010
comment
Это кажется еще одним доморощенным статическим методом. Возможно, он уже подавил это исключение внутри метода (что, кстати, действительно плохая идея). - person BalusC; 11.08.2010

Помимо ошибок компилятора, этот код не будет работать во время выполнения.

Когда вы закрываете Connection, из которого создается ResultSet, ResultSet становится недействительным, и любые вызовы к нему завершатся ошибкой. (Конечно, должен быть реализован какой-то странный драйвер JDBC, чтобы это могло работать, но это неправильное использование JDBC API.)

Область действия и время жизни ResultSet не может быть больше, чем его родительские Connection и Statement.

person erickson    schedule 11.08.2010

В написанном вами коде используется класс с типом исключения, которое необходимо обработать. Вы можете сделать это одним из двух способов, передав его вверх по цепочке, т.е. повторно выбрасывая исключение, или фактически обработав его, как показывают некоторые другие комментарии, поместив методы close в try catch их собственных в finally блокировать.

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

person user417639    schedule 11.08.2010