새로운 예외를 던지더라도 finally 블록이 실행됩니까?


142

이 코드에서는 someVarcatch 블록이 실행되고 두 번째 예외가 발생하더라도 설정됩니다.

public void someFunction() throws Exception {
    try {
        //CODE HERE
    } catch (Exception e) {
        Log.e(TAG, "", e);
        throw new Exception(e);
    } finally {
        this.someVar= true;
    }
}

2
@GaryF
jax

1
최종 블록이 예외를 발생 시키거나 리턴을 수행하면 최종 블록이 예상대로 실행되지 않을 수 있습니다.
피터 로리

답변:


184

예, finally 블록은 다음을 제외하고 항상 실행됩니다.

  • try-catch-finally 블록을 실행하는 스레드가 종료되었거나 중단되었습니다
  • 너는 사용한다 System.exit(0);
  • 기본 VM은 다른 방식으로 파괴됩니다
  • 어떤 방식 으로든 기본 하드웨어를 사용할 수 없습니다

또한 finally 블록의 메서드가 catch되지 않은 예외를 throw하면 그 이후에는 아무 것도 실행되지 않습니다 (예 : 다른 코드에서와 같이 예외가 발생 함). 이런 일이 발생하는 가장 일반적인 경우는 java.sql.Connection.close()입니다.

옆으로, 나는 당신이 사용한 코드 샘플이 단지 예일 것이라고 추측하지만 실제 논리를 finally 블록 안에 넣는 것에주의하십시오. finally 블록은 필수 논리가 아닌 리소스 정리 (DB 연결 닫기, 파일 핸들 해제 등)를위한 것입니다. try-catch 블록 전에 실행 해야하는 경우 의도가 기능적으로 거의 동일하기 때문에 예외가 발생할 수있는 것을 피하십시오.


4
"try-catch-finally 블록을 실행하는 스레드가 [...] 중단되었습니다"라는 의미는 무엇입니까? 아마도 문서화가 잘못되었지만 Thread.interrupt ()는 try 또는 catch 블록에서 throw했는지 여부에 따라 finally 블록을 건너 뛰지 않습니다. Thread.stop ()과 같이 더 폭력적인 것을 의미하기 위해 "인터럽트 된"을 사용합니까?
Joe Kearney

@Joe : 예, 나는이 문서화가 조금 잘못 표현되었다고 생각합니다. 그리고 그것들은 스레드의 활동에 대한 일반적인 중단을 의미합니다.
GaryF

@GaryF-JLS에서 인용 한 것 같습니다. JLS의 표현은 때때로 조금 이상하지만, 일반적으로 이상한 용어의 의미가 문서의 다른 곳에 명확하게 정의되어 있음을 알게 될 것입니다. JLS는 사양 이며 기본 목표로 가독성이 아닌 정밀도를 갖습니다.
Stephen C

1
@Stephen C-사실, 그것은 JavaSE 튜토리얼 (다른 사람들과 링크 됨)에서 나왔습니다. JLS에서도 비슷하게 표현 될 수 있지만 관련 부분을 찾을 수 없습니다. 11 장 (예외), 14 장 (문장) 또는 15 장 (표현)에서 이것을 예상했지만 명시 적으로 중단을 언급하는 것을 볼 수는 없습니다. 나는 그것을 보는 데 확실히 관심이 있습니다.
GaryF

1
@GaryF-알겠습니다. 실제로 JLS는 문장의 "정상적인"및 "급격한"종료에 대해 이야기하며 용어를 정의하는 섹션 (14.1)이 있습니다. finally그런 다음 동작은 정상 및 갑작스러운 종료와 관련하여 지정됩니다.
Stephen C

10

예.

설명서를 참조하십시오 :

finally 블록 은 try 블록이 종료 될 때 항상 실행됩니다.

예외 :

참고 : try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록이 실행되지 않을 수 있습니다. 마찬가지로 try 또는 catch 코드를 실행하는 스레드가 중단되거나 중단 된 경우 응용 프로그램 전체가 계속 진행 되더라도 finally 블록이 실행되지 않을 수 있습니다.


2

마지막으로 블록은 항상 실행됩니다.

public class ExceptionTest {

public static void someFunction(String input) throws Exception {
    try {
        if( input.equals("ABC") ) {
            System.out.println("Matched");
        }
    } catch (Exception e) {
        throw new Exception(e);
    } finally {
        System.out.println("Input Is "+input+" Finally Executed!!!");
    }
}

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
        System.out.println("********* Test with VALUE ********* ");
        someFunction("ABC");
        System.out.println("\r\n********* Test with NULL  ********* ");
        someFunction(null);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Java Try Catch 마침내 Throw로 차단


2

마지막으로 항상 사건이 무엇이든간에 실행됩니다.

  • try-catch-finally 블록
  • 던지다

확인되지 않은 예외의 경우 java는 오류 처리를 요구하지 않습니다. 이것이 검사되지 않은 예외가 finally 블록에서 발생하고 그에 대한 처리가 수행되지 않으면이 지점 아래에 작성된 코드 (오류가 발생한 위치)가 실행되지 않는 이유입니다.

따라서 항상 모든 예외를 처리하거나 확인하지 않을 것을 권장합니다. 이렇게하면 검사되지 않은 예외가 발생하더라도 최종적으로 코드 블록이 실행되도록 할 수 있습니다. 당신은 sub-nest catch에 장소를 가지고 있으며 필요한 작업을 수행하기 위해 마지막으로 차단합니다.



1

예. finallyJava VM을 중지하기 때문에 System.exit ()를 호출하는 경우를 제외하고 항상 블록이 실행됩니다.


종료 후크는 여전히 System.exit () 이후에 호출되지만 기존의 비 시스템 스레드는 모두 중지됩니다.
피터 로리
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.