В Java, как я устанавливаю тип возврата, если исключение происходит?

эй все, я плохо знаком с Java и задавался вопросом, определяю ли я метод для возврата объекта базы данных

как

import java.sql.*;

public class DbConn {

    public Connection getConn() {
        Connection conn;
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            if(System.getenv("MY_ENVIRONMENT") == "development") {
                String hostname = "localhost";
                String username = "root";
                String password = "root";
            }
            conn = DriverManager.getConnection("jdbc:mysql:///mydb", username, password);
            return conn;
        } catch(Exception e) {
            throw new Exception(e.getMessage());
        }

    }

}

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

спасибо!

ОБНОВЛЕННЫЙ КОД ДЛЯ РАЗРЕШЕНИЯ ПУЗЫРЮ ИСКЛЮЧЕНИЯ:

public class DbConn {

    public Connection getConn() throws SQLException {
        Connection conn;
        String hostname = "localhost";
        String username = "root";
        String password = "root";

        Class.forName("com.mysql.jdbc.Driver").newInstance();
        if(System.getenv("MY_ENVIRONMENT") != "development") {
            hostname = "localhost";
            username = "produser";
            password = "prodpass";
        }
        conn = DriverManager.getConnection("jdbc:mysql:///mydb", username, password);
        return conn;

    }

}
9
задан James 31 May 2010 в 19:42
поделиться

5 ответов

Если возникает исключение, метод не возвращает нормального значения. Обычно компилятор может это обнаружить, поэтому он даже не надоедает вам предупреждениями / ошибками в стиле «требуется возврат».Иногда, когда он не может этого сделать, вам нужно предоставить оператор возврата «алиби», который на самом деле никогда не будет выполнен.

Переопределение вашего метода таким образом

public Connection getConn() {
    Connection conn = null;
    try {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        if(System.getenv("MY_ENVIRONMENT") == "development") {
            String hostname = "localhost";
            String username = "root";
            String password = "root";
        }
        conn = DriverManager.getConnection("jdbc:mysql:///mydb", username, password);
    } catch(Exception e) {
        // handle the exception in a meaningful way - do not just rethrow it!
    }
    return conn;
}

удовлетворит Eclipse: -)

Обновление: Как отмечали другие, повторная генерация исключения в блоке catch, как вы это делали, не является хорошей идеей. Единственная ситуация, когда это является достойным решением, - это если вам нужно преобразовать между разными типами исключений. Например. метод с именем генерирует тип исключения, которое вы не можете или не хотите распространять вверх (например, потому что он принадлежит проприетарной библиотеке или фреймворку, и вы хотите изолировать от него остальную часть вашего кода).

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

public void doSomething() throws MyException {
    try {
        // code which may throw HibernateException
    } catch (HibernateException e) {
        logger.log("Caught HibernateException", e);
        throw new MyException("Caught HibernateException", e);
    }
}
7
ответ дан 4 December 2019 в 12:59
поделиться

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

Кроме того, какова цель строки Class.forName("com.mysql.jdbc.Driver").newInstance();? Вы создаете новый объект mysql Driver через отражение (почему?), но ничего с ним не делаете (почему?).

5
ответ дан 4 December 2019 в 12:59
поделиться

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

2
ответ дан 4 December 2019 в 12:59
поделиться

Это именно та ситуация, когда вы должны позволить исключению распространиться вверх по стеку вызовов (объявив метод как throws SQLException или обернув его в специфическое для приложения исключение), чтобы вы могли поймать и обработать его на более высоком уровне.

В этом весь смысл исключений: вы можете выбирать, где их ловить.

1
ответ дан 4 December 2019 в 12:59
поделиться

Извините, но вы не должны писать такой код, даже если вы новичок в Java.

Если вы должны написать такую вещь, я бы сделал ее более похожей на эту:

public class DatabaseUtils 
{

    public static Connection getConnection(String driver, String url, String username, String password) throws SQLException 
    {
        Class.forName(driver).newInstance();


        return DriverManager.getConnection(url, username, password);
    }
}

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

1
ответ дан 4 December 2019 в 12:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: