try에서 return했는데 finally의 return 값이 나온 이유
문제 발생
다음 메서드가 항상 false만 반환해서 원인을 찾다가, finally 블록의 return이 범인이라는 것을 발견했습니다.
public boolean process() {
try {
return true;
} finally {
return false; // 항상 이 값이 최종 반환됨
}
}원인 분석
finally 블록은 try(그리고 catch)가 어떤 방식으로 끝나든(정상 return, 예외 발생 등) 항상 실행되도록 설계되어 있습니다. 문제는 finally 안에 return문이 있으면, 그 return이 try/catch에서 이미 결정된 반환값이나 발생한 예외를 완전히 덮어써버린다는 점입니다.
심지어 try 블록에서 예외가 발생했더라도, finally에 return이 있으면 그 예외는 전파되지 않고 조용히 삼켜집니다 — 이건 더 위험한 함정입니다. 예외가 발생했다는 사실 자체가 사라지므로 디버깅이 극도로 어려워집니다.
public int risky() {
try {
throw new RuntimeException("문제 발생");
} finally {
return 0; // 예외가 무시되고 0이 반환됨 — 예외가 삼켜짐
}
}해결 방안
finally블록 안에return/break/continue를 쓰지 않는 것을 원칙으로 합니다. 대부분의 정적 분석 도구(SonarQube, IntelliJ 검사 등)가 이 패턴을 경고로 잡아줍니다.finally는 리소스 정리(파일 닫기, 락 해제 등) 용도로만 씁니다 — 반환값 결정 로직은try/catch안에서 끝내야 합니다.- try-with-resources를 쓸 수 있는 상황(
Closeable리소스)이라면finally로 직접close()를 호출하는 대신 그쪽을 우선 씁니다 — 이 함정 자체를 피할 수 있습니다. - 이미 있는 코드에서 이 패턴을 발견했다면, 왜
finally에return을 넣었는지(의도적인지 실수인지) 먼저 확인하고, 실수라면 조기에 고쳐야 합니다 — 이런 코드는 겉보기엔 멀쩡히 컴파일되고 실행되어 리뷰에서 놓치기 쉽습니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.