Возврат из метода, в блок "try" или после "catch" block?
Есть ли разница между следующими двумя методами?
Какой из них предпочтительнее и почему?
PRG1:
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
PRG2:
public static boolean test() throws Exception {
try {
doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return true;
}
Ответы
Ответ 1
Рассмотрим эти случаи, когда вы не возвращаете постоянное выражение:
Случай 1:
public static Val test() throws Exception {
try {
return doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
// Unreachable code goes here
}
Случай 2:
public static Val test() throws Exception {
Val toReturn = null;
try {
toReturn = doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return toReturn;
}
Я бы предпочел первый. Второй - более подробный и может вызвать некоторую путаницу при отладке.
Если test()
неверно возвращает null
, и вы видите, что toReturn
инициализируется на null
, вы можете подумать, что проблема находится в test()
(особенно, когда test()
- это не просто простой пример).
Даже если он возвращает только null
, если doSomething
возвращает null
. Но это может быть трудно увидеть с первого взгляда.
Тогда вы могли бы утверждать, что для обеспечения согласованности лучше всегда использовать первую форму.
Ответ 2
Нет никакого различия между этими методами.
Он вернет истинное значение в обоих случаях эффективно, возобновив поток программы, как только будет обработано исключение.
Доступ к Catch будет доступен только в случае возникновения исключения.
Ответ 3
Функциональной разницы нет. Обе программы ведут себя одинаково.
Это всего лишь стиль кодирования и личного вкуса.
Как хорошая практика, лучше иметь один оператор возврата для каждого метода - в конце метода вместо промежуточного. В случае длинных блоков кода этот стиль делает код более читабельным и более удобным в будущем, когда (оригинальный автор или кто-то еще) должен внести изменения в код.
Следовательно, первая считается лучшей с точки зрения хорошей практики.
Ответ 4
Я предполагаю, что это общий вопрос. В противном случае я могу прокомментировать другие аспекты вашего метода.
Я думаю, что в случае или таких небольших методах это не имеет большого значения. Метод достаточно короткий, чтобы сразу понять, что происходит, что связано с тем, что и т.д.
Однако в случае более длинных методов в первом примере поток намного проще выполнить. По моему мнению. Он поддерживает взаимосвязанный код и связанные с ним сценарии. Когда вы читаете метод, нормальный поток выполнения не разбивается блоком catch
, делая его более очевидным и "плавным".
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
Но я не буду обобщать это для всех методов; это все о контексте.
Ответ 5
Нет никакой разницы, но первый Prg1 быстрее, чем Prg2.