finally 블록을 사용하는 이유는 무엇입니까?


91

내가 알 수있는 한, 다음 코드 스 니펫은 모두 동일한 용도로 사용됩니다. 왜 finally블록이 있습니까?

코드 A :

try { /* Some code */ }
catch { /* Exception handling code */ }
finally { /* Cleanup code */ }

코드 B :

try { /* Some code */ }
catch { /* Exception handling code */ }
// Cleanup code

이것은 C #에만 국한되지 않고 .Net 질문입니다
Sruly

1
java7에서 더 이상 필요 없음 : AutomaticResourceManagement, try (new resourceDeclartion ()) {}
Kanagavelu Sugumar

답변:


139
  • 처리하지 않는 예외가 발생하면 어떻게됩니까? (잡지 않았 으면 좋겠다 Throwable...)
  • try 블록 내부에서 돌아 오면 어떻게됩니까?
  • catch 블록에서 예외가 발생하면 어떻게됩니까?

finally블록이 있는지 확인합니다 그러나 당신이 그 블록 (명시 적으로 전체 프로세스를 중단하는 몇 가지 방법을 모듈로),이 실행 얻을 것이다를 종료합니다. 이는 결정 론적 리소스 정리에 중요합니다.


48
반드시 사실은 아닙니다. (1) System.exit()호출이있는 경우 (2) try 또는 catch 블록 중 하나에 무한 루프가있는 경우 마지막으로 실행되지 않습니다. (3) 컴퓨터에서 플러그를 뽑습니다
NullUserException

2
@Alon try {return 1; } finally {retrun 2; } 당신이 얻을 것이다
데니스 C

19
@NullUserException : 따라서 비트 "몇 가지 방법 ... 모듈로"
존 소총

2
존 스키트에 유래 여기에 살고, 모든 문제는 그가 :) 대답에이 울리는 초인종처럼
naikus

1
이 게시물 은 마침내 호출되지 않는 (드문) 조건에 대해 설명합니다.
Candamir

13

(적어도 Java에서는 C #에서도 가능)가없는 try블록 을 가질 수도 catch있지만 finally. 예외가 발생했을 때에 try블록의 코드에서 finally예외가 높은 곳을 던져 전에 블록이 실행됩니다 :

InputStream in = new FileInputStream("somefile.xyz");
try {
    somethingThatMightThrowAnException();
}
finally {
    // cleanup here
    in.close();
}

7

try 또는 catch 블록에서 발생하는 일과 관계없이 어쨌든 실행하려는 코드를 넣을 수 있습니다.

또한 다중 catch를 사용하고 있고 모든 catch 블록에 공통적 인 일부 코드를 넣으려면 여기에 넣을 수 있습니다. 그러나 try의 전체 코드가 실행되었는지 확인할 수는 없습니다.

예를 들면 :

conn c1 = new connection();
try {
    c1.dosomething();
} catch (ExceptionA exa) {
    handleexA();
    //c1.close();
} catch (ExceptionB exb) {
    handleexB();
    //c1.close();
} finally {
    c1.close();
}

1
'finally'를 사용하지 않고 연결을 종료하면 어떻게됩니까?
Istiaque Ahmed

5

마지막으로 항상 실행되며, catch 후 코드는 그렇지 않을 수 있습니다.


1
왜 안돼! 예외가 제대로 처리되면 코드가 확실하게 실행됩니다.
Mohammad Nadeem

1
@Nadeem : 3 가지 이유로 내 대답을 참조하십시오.
Jon Skeet

2

응용 프로그램이 강제로 닫혔더라도 실행해야하는 작업 (메모리 해제, 데이터베이스 닫기, 잠금 해제 등)이있을 것입니다. 이러한 코드 줄을 finally블록 에 작성 하면 예외가 발생하거나 아니...

응용 프로그램은 스레드 모음 일 수 있으며 스레드를 Exception종료하지만 전체 응용 프로그램은 아닙니다.이 경우 finally더 유용합니다.

finallyJVM 실패, 스레드 종료 등과 같은 일부 경우 에는 실행되지 않습니다.


1

throw 될 수있는 예외에 관계없이 실행하려면 해당 코드가 필요하기 때문입니다. 예를 들어 일부 관리되지 않는 리소스를 정리해야 할 수 있습니다 ( 'using'구문은 try / finally 블록으로 컴파일 됨).


0

무슨 일이 있어도 코드를 실행하고 싶을 때가 있습니다. 예외 발생 여부입니다. 그런 다음 finally.


0

finallyJVM이 종료되지 않는 한 ALWAYS는 finally단지 한곳에 정리 코드를 넣는 방법을 제공합니다.

catch블록 에 정리 코드를 넣어야한다면 너무 지루할 것 입니다.


0

catch 블록이 예외를 던지면 나머지 코드는 실행되지 않으므로 finaly 블록을 작성해야합니다.


0

finally 블록은 파일 닫기, 연결 닫기 등과 같은 "정리"코드를 넣는 데 사용할 수 있습니다.


finally 블록은 프로그램이 종료되면 (System.exit ()를 호출하거나 프로세스를 중단시키는 치명적인 오류를 유발하여) 실행되지 않습니다.


0

여전히 아래로 스크롤 하시겠습니까? 여기 있습니다!

이 질문은 저에게 한동안 힘든 시간을주었습니다.

try
{
 int a=1;
 int b=0;
 int c=a/b;
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}
finally
{
 console.writeline("Finally block");
}
console.writeline("After finally");

위의 시나리오에서 무엇이 인쇄됩니까? 네 맞아요 :

  • ex. 메시지-그것이 무엇이든간에 (아마도 0으로 나누기를 시도 함)

  • 마지막으로 차단

  • 드디어

    try
    {
        int a=1;
        int b=0;
        int c=a/b;
    }
    catch(Exception ex)
    {
        throw(ex);
    }
    finally
    {
        console.writeline("Finally block");
    }
    console.writeline("After finally");
    

이것은 무엇을 인쇄할까요? 아무것도! catch 블록에서 오류가 발생했기 때문에 오류가 발생합니다.

좋은 프로그래밍 구조에서는이 코드가 다른 레이어에서 처리된다는 점에서 예외가 퍼널 링됩니다. 이러한 경우를 자극하기 위해 중첩 된 코드를 사용해 보겠습니다.

try
{    
 try
    {
     int a=1;
     int b=0;
     int c=a/b;
    }
    catch(Exception ex)
    {
     throw(ex);
    }
    finally
    {
     console.writeline("Finally block")
    }
    console.writeline("After finally");
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}

이 경우 출력은 다음과 같습니다.

  • 마지막으로 차단
  • 예. 메시지-그것이 무엇이든.

예외를 포착하여 다른 레이어 (Funneling)로 다시 던지면 throw 후 코드가 실행되지 않음이 분명합니다. 함수 내부의 리턴이 작동하는 방식과 유사하게 작동합니다.

이제 catch 블록 이후에 코드에서 리소스를 닫지 않는 이유를 알았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.