Java - Переменная область действия в try-catch - Контраст между большинством ответов и официальным руководством Java - PullRequest
0 голосов
/ 15 января 2020

Я читал следующее официальное руководство и обнаружил проблему: совместное использование этих двух фрагментов кода приведет к ошибке (нет области действия для объекта stmt):

Обработка объектов ResultSet

try {
    stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(query);
    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");
        int sales = rs.getInt("SALES");
        int total = rs.getInt("TOTAL");
        System.out.println(coffeeName + "\t" + supplierID +
                           "\t" + price + "\t" + sales +
                           "\t" + total);
    }
}

Закрытие соединений

} finally {
    if (stmt != null) { stmt.close(); }
}

Если я попытаюсь stmt.close() в блоке finally, я получить ошибку, потому что в его области видимости нет переменной stmt, и это потому, что (насколько я понимаю) фактическая область действия объекта stmt находится в блоке try.

Мой вопрос прост, эти два блока кода работают вместе?

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

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

Большое спасибо всем, кто попытается мне помочь.

Ответы [ 2 ]

0 голосов
/ 15 января 2020

, чтобы сделать это явным, вы должны присвоить stmt значение null, чтобы оно существовало и инициализировалось:

Statement stmt = null;
try {
    stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(query);
    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");
        int sales = rs.getInt("SALES");
        int total = rs.getInt("TOTAL");
        System.out.println(coffeeName + "\t" + supplierID +
                           "\t" + price + "\t" + sales +
                           "\t" + total);
    }
} finally {
    if (stmt != null) { stmt.close(); }
}
0 голосов
/ 15 января 2020

Предположительно, вы объявили объект stmt внутри try, а не снаружи. Код должен выглядеть следующим образом:

Statement stmt;
try {
    stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(query);
    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");
        int sales = rs.getInt("SALES");
        int total = rs.getInt("TOTAL");
        System.out.println(coffeeName + "\t" + supplierID +
                           "\t" + price + "\t" + sales +
                           "\t" + total);
    }
} finally {
    if (stmt != null) { stmt.close(); }
}

Однако вы можете использовать тот факт, что Statement реализует AutoClosable и фактически пропускает блок finally, используя try with resources (функция Java добавлена ​​в Java 6 ир c). Это будет выглядеть так:

try (Statement stmt = con.createStatement()) {
    ResultSet rs = stmt.executeQuery(query);
    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");
        int sales = rs.getInt("SALES");
        int total = rs.getInt("TOTAL");
        System.out.println(coffeeName + "\t" + supplierID +
                           "\t" + price + "\t" + sales +
                           "\t" + total);
    }
} catch (SQLException e) {
     // Log it
}

Подробнее о AutoClosable и try with resources можно прочитать здесь:

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

...