Как return работает в try, catch, наконец в Java? - PullRequest
0 голосов
/ 26 июня 2018

Я не могу точно понять, как return работает в try, catch.

  • Если у меня есть try и finally без catch, я могу поставить return внутри блока try.
  • Если у меня есть try, catch, finally, я не могу поместить return в блок try.
  • Если у меня есть блок catch, я должен поставить return вне блоков try, catch, finally.
  • Если я удаляю блок catch и throw Exception, я могу поместить return в блок try.

Как они работают точно? Почему я не могу поместить return в блок try?

Код с try, catch, finally

 public int insertUser(UserBean user) {
     int status = 0;

     Connection myConn = null;
     PreparedStatement myStmt = null;

     try {
         // Get database connection
         myConn = dataSource.getConnection();

         // Create SQL query for insert
         String sql = "INSERT INTO user "
                    + "(user_name, name, password) "
                    + "VALUES (?, ?, ?)";

         myStmt = myConn.prepareStatement(sql);

         // Set the parameter values for the student
         myStmt.setString(1, user.getUsername());
         myStmt.setString(2, user.getName());
         myStmt.setString(3, user.getPassword());

         // Execute SQL insert
         myStmt.execute();
     } catch (Exception exc) {
         System.out.println(exc);
     } finally {
         // Clean up JDBC objects
         close(myConn, myStmt, null);
     }

     return status;
 }

Код с try, finally без catch

 public int insertUser(UserBean user) throws Exception {
     int status = 0;

     Connection myConn = null;
     PreparedStatement myStmt = null;

     try {
         // Get database connection
         myConn = dataSource.getConnection();

         // Create SQL query for insert
         String sql = "INSERT INTO user "
                    + "(user_name, name, password) "
                    + "VALUES (?, ?, ?)";

         myStmt = myConn.prepareStatement(sql);

         // Set the parameter values for the student
         myStmt.setString(1, user.getUsername());
         myStmt.setString(2, user.getName());
         myStmt.setString(3, user.getPassword());

         // Execute SQL insert
         myStmt.execute();

         return status;
     } finally {
         // Clean up JDBC objects
         close(myConn, myStmt, null);
     }
 }

Ответы [ 7 ]

0 голосов
/ 26 июня 2018

При использовании общедоступных функций, отличных от void, вы должны что-то вернуть, иначе ваша функция не будет.

0 голосов
/ 01 июля 2018

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

так что когда блок finally будет выполняться в потоке ...

если у нас есть оператор return внутри блока try / catch , то перед выполнением оператора return наконец будет выполнен блок (как при закрытии соединения или I / O)

function returnType process() {
  try {
      // some other statements
      // before returning someValue, finally block will be executed
      return someValue;
  } catch(Exception ex) {
     // some error logger statements
     // before returning someError, finally block will be executed
     return someError;
  } finally {
    // some connection/IO closing statements
    // if we have return inside the finally block
    // then it will override the return statement of try/catch block
    return overrideTryCatchValue;
  }
}

но если у вас есть оператор return внутри оператора finally , тогда он переопределит оператор возврата внутри блока try или catch.

0 голосов
/ 26 июня 2018

И если у меня есть попытка, поймай, наконец, я не могу поместить return в блок try.

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

Например, следующие работы:

int foo() throws Exception { … }

int bar() throws Exception {
    try {
        final int i = foo();
        return i;
    } catch (Exception e) {
        System.out.println(e);
        throw e;
    } finally {
        System.out.println("finally");
    }
}

Здесь у вас есть два возможных пути выполнения:

  1. final int i = foo()
  2. либо
    1. System.out.println("finally")
    2. return i
  3. или
    1. System.out.println(e)
    2. System.out.println("finally")
    3. throw e

Путь (1, 2) берется, если foo не выдано исключение. Путь (1, 3) берется, если выдается исключение. Обратите внимание, как в обоих случаях блок finally выполняется до , когда метод остается.

0 голосов
/ 26 июня 2018

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

Если вы добавили инструкцию return в блок try-finally, и у вас нет блока catch, это нормально.Здесь нет случая ненормального пути к коду.

Если вы добавили инструкцию return в блок try и у вас есть блок catch, то вы можете добавить return в блок catch или в конце метода.

Если вы добавили оператор return в блок try и у вас есть блок catch и, наконец, блок, то вы можете добавить return в блоке catch или в конце метода.Вы также можете добавить возврат в блок finally.Если вы используете eclipse, он выдаст предупреждение, которое можно подавить, используя приведенное ниже определение метода -

@SuppressWarnings("finally")
0 голосов
/ 26 июня 2018

Во втором примере, если возникает проверенное исключение, оно переходит к вызову метода.

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

если вы напишете инструкцию возврата в блоке catch, то это сработает.
т.е.

try{  
    return ..  
}catch(Exception e){  
    return ..  
}finally{  
}

Но это не хорошопрактика программирования.

0 голосов
/ 26 июня 2018

Я думаю, это то, что вы спрашиваете:

И если у меня есть попытка, поймайте, наконец, я не могу поместить return в блок попытки.

Таким образом, если вы добавляете блок catch, вы не можете поместить return в блок try.

Проблема в том, что если вы добавите catch, тогда элемент управления пропадет через и вам нужен return в конце метода, или это синтаксическая ошибка.Я не проверял это, но я предполагаю, что вы могли бы поместить return в блок try, но вам также придется добавить его в catch или в конце метода каку вас сейчас.

0 голосов
/ 26 июня 2018

Да, это сбивает с толку.

В Java все пути управления программой не-1005 * функции должны заканчиваться return или вызывать исключение. Это правило, изложенное красиво и просто.

Но в мерзости Java позволяет вам поместить extra return в блок finally, который переопределяет все ранее встречавшиеся return:

try {
    return foo; // This is evaluated...
} finally {
    return bar; // ...and so is this one, and the previous `return` is discarded
}
...