Java에서 try가 값을 반환하려는 도중 finally가 정상적으로 끝나면 원래 반환 흐름이 이어집니다. 그러나 finally가 또 return하여 정상 완료가 아닌 완료를 만들면 앞선 반환 흐름을 덮고, finally의 값이 호출자에게 전달됩니다.

이 동작은 언어 규칙을 추적하기 위한 예제입니다. 실제 코드에서는 finally의 return이 예외나 앞선 반환을 가릴 수 있으므로 그런 제어 흐름을 피하는 편이 안전합니다.

finally가 정상 완료인지 먼저 확인합니다

return을 만나도 Java는 메서드를 즉시 끝내기 전에 실행해야 하는 finally 블록을 실행합니다. finally가 정상적으로 완료되면 원래 계산된 반환 값으로 호출자에게 돌아갑니다. 그러나 finally가 새로운 return을 실행하거나 예외를 던져 abrupt completion을 만들면, 기존의 return 흐름은 그 새로운 완료에 의해 대체될 수 있습니다. 따라서 코드 추적에서는 try의 반환문만 보고 답을 정하지 말고 finally가 어떻게 끝나는지 확인해야 합니다.

두 return이 같은 메서드에서 충돌하는 예제

교육용 언어 의미 추적 예시이며 권장 코딩 스타일이나 공식 기출이 아닙니다.
static int choose() {
  try { return 1; }
  finally { return 2; }
}
System.out.println(choose());
완료 상태를 시간 순서로 읽습니다
순서문장메서드 상태
1try의 return 11을 반환하려는 흐름을 준비
2finally 진입반환 전에 finally 실행
3finally의 return 2새 반환 흐름이 기존 흐름을 대체
4호출자2를 받음

첫 번째 문장은 1을 반환하려고 하지만, 실제 반환 전에 finally가 실행됩니다. 그 블록이 정상 종료하지 않고 2를 반환하기 때문에 호출자는 2를 받습니다. finally에서 return을 제거하고 블록을 정상적으로 끝내면 호출자는 원래 준비된 1을 받습니다. 즉 결과는 어느 return이 텍스트상 더 아래에 있느냐가 아니라, finally가 정상 완료하는지에 달려 있습니다.

반환과 예외를 완료 종류로 나눕니다

  1. try 또는 catch에서 return·예외를 만나면 그 완료를 메모합니다.
  2. finally 블록이 있으면 항상 실행되는 경로를 확인합니다.
  3. finally가 정상 완료하면 저장한 완료가 이어지는지 봅니다.
  4. finally가 return 또는 예외로 갑자기 끝나면 그 새 완료가 호출자에 전달되는지 확인합니다.

시험 결과와 안전한 코드 스타일을 구별합니다

finally의 return을 보고하지 말라는 코딩 권고와, 이미 작성된 코드가 실제로 어느 값을 반환하는지는 서로 다른 질문입니다. 문제에서 결과를 물으면 언어 규칙대로 2를 답해야 합니다. 코드 리뷰에서는 이 return이 앞선 값을 가리고, finally에서 발생한 예외가 원래 예외를 가릴 수 있다는 점을 지적할 수 있습니다. 자원 정리는 finally나 try-with-resources로 하고, 반환 결정은 일반 경로에서 명확히 하는 편이 추적과 유지보수에 유리합니다. 이 글은 finally의 일반 제어 흐름만 다루며 예외 우선순위 전체를 열거하지 않습니다.

반환값 계산과 finally 실행을 나누면 결과를 더 정확히 읽을 수 있습니다. 기본형 지역 변수를 반환하는 식은 finally가 실행되기 전에 평가됩니다. try가 현재 값을 반환하려고 준비한 뒤 finally가 지역 변수만 바꾸고 정상 종료하면 호출자는 준비된 값을 받습니다. 반면 finally가 return으로 abrupt completion을 만들면 새 반환 흐름이 앞선 흐름을 대체합니다. 이 두 경우를 같은 규칙으로 취급하지 마세요. 문제에서 실제 값을 묻는 경우와 코드 리뷰에서 finally 안의 return을 피하라고 조언하는 경우도 서로 다른 답변입니다.

정답을 가리고 확인해 보세요

이 글을 위해 만든 학습 예시이며 공식 기출문제나 판매 카드의 인용이 아닙니다.

try가 1을 반환하고 finally가 2를 반환하는 Java 메서드의 결과는 무엇인가요?

정답과 해설 확인2입니다.

JLS의 abrupt completion 규칙에 따라 finally가 정상 완료가 아닌 return으로 끝나면 앞선 반환 흐름을 대체합니다. 정상 완료하는 finally라면 원래 return이 이어집니다.