Подтвердить что ты не робот

Return в try-catch наконец-то блокируется в java. Есть ли хороший пример в этом примере?

Я не знаком с java, и я недавно смотрел какой-то код, написанный некоторыми коллегами, который меня озадачил. Вот его суть:

public response newStuff(//random data inside) {
    try {
       response or = //gives it a value
       log.info(or.toString());
       return or;
    }
    catch ( Exception e) {
        e.printStackTrace();
    }
    finally {
        return null;
    }
}

Есть ли какая-нибудь точка добавления блока finally здесь? Могу ли я просто добавить возвращаемый null внутри блока catch, который будет выполнять одно и то же поведение, или я не прав?

4b9b3361

Ответ 1

Есть ли какая-нибудь точка добавления блока finally здесь?

Ответ на это - громкое "нет": размещение инструкции return в блоке finally - очень плохая идея.

Я просто добавляю возвращаемый null внутри блока catch, который будет выполнять одно и то же поведение, или я ошибаюсь?

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

Кроме того, если вы добавите return null после блока catch, вы увидите правильный эффект возврата null в исключение. Я бы пошел еще дальше и поместил в метод один return, например:

response or = null;
try {
   or = //gives it a value
   log.info(or.toString());
} catch ( Exception e) {
    e.printStackTrace();
}
return or;

Ответ 2

Собственно, нет. Наконец, (почти) всегда выполняется, независимо от результата в блоке try-catch; поэтому этот блок всегда возвращает null. Здесь рассмотрим этот пример:

public class Finally {

/**
 * @param args
 */
public static void main(String[] args) {
    System.out.println(finallyTester(true));
    System.out.println(finallyTester(false));
}

public static String finallyTester(boolean succeed) {
    try {
        if(succeed) {
            return "a";
        } else {
            throw new Exception("b");
        }
    } catch(Exception e) {
        return "b";
    } finally {
        return "c";
    }
  }

}

Он будет печатать "c" оба раза.

Вышеупомянутое исключение из правила было бы, если сам поток прерывается; например на System.exit(). Это, однако, редко случается.

Ответ 3

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

Ответ 4

Это выглядит очень плохой практикой. В этом случае ваш код всегда будет возвращать null.

Блок finally вызывается последним после запуска блока try-catch. Независимо от того, был ли завершен try или был выведен блок exception. В этом случае, независимо от того, какой путь кода запущен, вы всегда будете возвращать null. В "нормальном" случае, когда вы помещаете return null после того, как наконец-то есть шанс что-то вернуть (либо из try, либо из блока catch), и если поток не возвращает объект возврата, вы отступаете к return null, но вы не всегда возвращаете null.

Ответ 5

Я читал, что многие люди просто отвечают "не используйте return в блоке finally", без каких-либо объяснений. Ну, на самом деле код, который вы опубликовали, является хорошим примером, где return в блоке finally вызывает серьезную путаницу. Даже, со времени написания этого наиболее одобренного ответа, получил неправильный. Ваш код всегда будет выполнять return null; в качестве последней команды даже если есть Исключение.

Но я могу думать о ситуации, когда блок return в блоке finally действительно имеет смысл. Мне кажется, что целью автора вашего кода было то, что метод никогда не выбрасывает Throwable, а возвращает null вместо. Это может быть достигнуто, если вы измените код следующим образом:

public Result newStuff() {
    Result res = null;
    try {
       res = someMethod();
       log.info(res.toString());
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        return res;
    }
}

Но обратите внимание, что это не вызовет printStackTrace() на Error и Throwable, которые не являются Exception s.

Ответ 6

Блок "Наконец" будет выполняться независимо от того, срабатывает ли "Catch" или нет. Таким образом, поведение отличается от того, что вы просто положили "return null" в блок Catch.

Ответ 7

В блоке finally не должно быть оператора return, удалите return.

Ответ 8

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

В вашем случае вы пишете метод, в котором вы возвращаете что-то в блоке try, и в конце вы пишете, наконец, блок, где вы возвращаете null. Я не вижу в этом никакого использования блока finally.

Ответ 9

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

Ответ 10

Сначала поймите, зачем нам нужны эти три блока в простых словах для начинающих.

1) try block: Если у вас есть сомнения, что ваш код приведет к исключению, тогда поставьте блок try

2) catch block: Если возникает исключение, тогда фрагмент кода, который вам нужно выполнить, должен быть записан в этом блоке

3) finally block: Если вы хотите, чтобы ваш фрагмент кода выполнялся, не имеет значения, возникает ли исключение или нет, тогда мы идем для окончательного блока. В основном этот блок используется для освобождения ресурсов. Например:

try{
   Connection conn=//something;
   //some code for database operations

}catch(SQLException e){
        e.printStackTrace()
}finally{
      conn=null;
}

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

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