Java: попробуйте, наконец, выполнить кастинг
Я запутался в выполнении try-finally, когда в блоке try существует return;
. В моем понимании блок finally всегда будет выполнен, то есть перед возвратом к вызывающему методу. Рассматривая следующий простой код:
public class TryCatchTest {
public static void main(String[] args){
System.out.println(test());
}
static int test(){
int x = 1;
try{
return x;
}
finally{
x = x + 1;
}
}
}
Результат напечатан на самом деле 1. Означает ли это, что блок finally не выполняется? Может ли кто-нибудь помочь мне с этим?
Ответы
Ответ 1
Когда вы возвращаетесь из блока try
, возвращаемое значение сохраняется в фрейме стека для этого метода. После этого выполняется блок finally.
Изменение значения в блоке finally не изменит значение уже в стеке. Однако, если вы снова вернетесь из блока finally, возвращаемое значение в стеке будет перезаписано, и будет возвращен новый x
.
Если вы напечатаете значение x
в блоке finally, вы узнаете, что оно выполнено, и будет напечатано значение x
.
static int test(){
int x = 1;
try{
return x;
}
finally{
x = x + 1;
System.out.println(x); // Prints new value of x
}
}
Примечание: В случае возвращаемого ссылочного значения значение ссылки сохраняется в стеке. В этом случае вы можете изменить значение объекта, используя эту ссылку.
StringBuilder builder = new StringBuilder("");
try {
builder.append("Rohit ");
return builder;
} finally {
// Here you are changing the object pointed to by the reference
builder.append("Jain"); // Return value will be `Rohit Jain`
// However this will not nullify the return value.
// The value returned will still be `Rohit Jain`
builder = null;
}
Рекомендуемое чтение:
Ответ 2
Выполняется блок finally. Локальная переменная увеличивается. Но значение этой локальной переменной уже скопировано для возвращаемого значения.
Из спецификации языка Java, 14.17: Оператор return:
Оператор return с выражением пытается передать управление вызывающему метода, который содержит его; значение выражения становится значением вызов метода.
...
В предыдущих описаниях говорится "попытки передать управление", а не просто "передачи control", потому что если в методе или конструкторе есть какие-либо попытки (§14.20) чьи блоки try или catch содержат оператор return, тогда любой положения этих заявлений о попытках будут выполнены, чтобы быть наиболее внутренним до внешнего управление передается вызову метода или конструктора. Резкое завершение finally может нарушить передачу управления, инициированного оператором return
Ответ 3
Вы возвращаете x перед тем, как выйти из try. Я бы сделал это:
public class TryCatchTest {
public static void main(String[] args) {
System.out.println(test());
}
static int test() {
int x = 1;
try {
do something with x.
} finally {
do something that will happen even in case of error;
x = x + 1;
return x;
}
}
}