Учитывая этот код:
String test() {
try {
return "1";
} finally {
return "2";
}
}
Сделайте спецификации языка определяют возвращаемое значение вызова к test()
? Другими словами: это всегда - то же в каждой JVM?
В JVM солнца возвращаемое значение 2
, но я хочу быть уверенным, что это не VM-иждивенец.
Да, спецификация языка определяет, что "2" - это результат. Если ВМ делает это по-другому, она не соответствует спецификации.
Большинство компиляторов будут жаловаться на это. Eclipse, например, заявит, что блок возврата никогда не будет выполнен, но это неверно.
Это шокирующе плохая практика писать такой код, никогда не делайте этого :)
Да, в Спецификации языка Java очень ясно сказано по этому вопросу (14.20.2):
Оператор try с блоком finally выполняется путем выполнения сначала блока try. Затем есть выбор:
- Если выполнение блока try завершается нормально, [...]
- Если выполнение блока try завершается внезапно из-за выброса значения V, [...]
- Если выполнение блока try завершается внезапно по любой другой причине R, то выполняется блок finally. Затем есть выбор:
- Если блок finally завершается нормально, [...]
- Если блок finally завершается внезапно по причине S, то оператор try завершается внезапно по причине S (и причина R отбрасывается).
Блок finally всегда будет выполняться, за исключением следующего примера:
String test() {
try {
System.exit(0);
} finally {
return "2";
}
}
В этом случае JVM остановится, не выполнив блок finally
.
Таким образом, в вашем примере возвращаемое значение будет 2
.
Да, если вы вернете что-то из блока finally
, это заменит то, что вы могли вернуть из блока try
или catch
.
То же самое справедливо и для исключений. Если вы бросите что-то в блоке finally
, это исключение заменит исключение, брошенное в блоке try
или catch
. Поэтому будьте осторожны и не выбрасывайте ничего в блоке finally
, потому что это может скрыть первоначальную причину неудачи.