programing

시도에서 최종적으로 사용해야 하는 이유또 만나

javajsp 2023. 5. 29. 09:42

시도에서 최종적으로 사용해야 하는 이유또 만나

나는 그것은FinallyTry .. Catch항상 시도 캐치 블록의 실행 부분 후에 실행됩니다.

그냥 건너뛰는 것이 다른가요?Finally트라이 캐치 블록 밖에서 섹션을 실행하고 그냥 실행하는 것입니까?

예 1, 시도...캐치...마지막으로...시도 종료

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    Finally
        'Do cleanup
    End Try

예 2, 시도...캐치...시도 종료...밖에서 마지막 일을 하세요.

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    End Try
    'Do cleanup

네, 다릅니다.마지막으로 항상 실행됩니다(프로그램 충돌 제외).기능이 try catch 블록 내부에서 종료되거나 try 또는 catch에 다른 오류가 발생한 경우에도 가 계속 실행됩니다.마지막 문을 사용하지 않으면 해당 기능을 사용할 수 없습니다.

네 개의 라디오 버튼이 있는 코드:

  • TRY로 돌아가기
  • CATCH에서 반환
  • CATCH 투입
  • CATCH

    private void checkFinally()
    {
        try
        {
            doFinally();
        }
        catch
        {
            Console.WriteLine(" Breaking news: a crash occured. ");
        }
    }
    
    private void doFinally()
    {
        Console.WriteLine(" ");
        Console.Write("Here goes: " 
            + (radioReturnInTry.Checked ? "2. Return in try: " 
                    : (radioReturnInCatch.Checked? "3. Retrun in catch: "
                        : (radioThrowInCatch.Checked? "4. Throw in catch: "
                            : "1. Continue in catch: "))) );
        try
        {
            if (radioReturnInTry.Checked)
            {
                Console.Write(" Returning in try. ");
                return;
            }
            Console.Write(" Throwing up in try.  ");
            throw new Exception("check your checkbox.");
        }
        catch (Exception ex)
        {
            Console.Write(" ...caughtcha! ");
            if (radioReturnInCatch.Checked)
            {
                Console.Write("Returning in catch. ");
                return;
            }
            if (radioThrowInCatch.Checked)
            {
                Console.Write(" Throwing up in catch. ");
                throw new Exception("after caught");
            }
        }
        finally { Console.Write(" Finally!!"); }
        Console.WriteLine(" Done!!!"); // before adding checkboxThrowInCatch, 
        // this would never happen (and was marked grey by ReSharper)
    
    }
    

출력:

  • 갑니다: 1.계속 캐치:시도 중에 토하는 것. ...차를 잡았습니다!드디어!됐습니다!!!
  • 갑니다: 2.Return in try: Return in try.드디어!
  • 갑니다: 3.캐치에서 다시 실행:시도 중에 토하는 것. ...차를 잡았습니다!포획물을 가지고 돌아옵니다.드디어!
  • 갑니다: 4.캐치 인:시도 중에 토하는 것. ...차를 잡았습니다!캐치볼.드디어!속보: 충돌이 발생했습니다.

요약:마지막으로 다음 두 가지를 처리합니다.

  1. 시도 또는 캐치에서 반환된 코드입니다.
  2. 아니면 시도에서 예외가 있고, 캐치에서 예외를 던진다면,
  3. 아니면, 당신이 시도에서 예외가 있었지만 그 예외를 잡지 못했다면,

마지막으로 "FINALY"를 요약합니다.마지막으로 당신이 노력했다면 특별한 것은 아무것도 하지 않습니다.

  1. 돌아오지 않았습니다.
  2. 그리고 재판 중에 예외를 포착했고, 그리고 나서.
  3. 포획물에서도 돌아오지 않았고, 그리고.
  4. 던지지 않았거나 토하는 코드가 없습니다.

그리고 마지막으로 (마지막으로):코드에 감지되지 않은 예외가 있는 경우 코드는 최종적으로 도달하지 않고 이동합니다.

이것이 확실하기를 바랍니다.(이제 나에겐...)

모셰

다른 점은 코드가 다음과 같은 경우입니다.try은 예던를집다에 않는 . 예외를 던집니다.catch블록으로 막다

은 일적으로.catch블록은 특정 유형의 예외를 탐지하고 다른 항목을 통과합니다.그런경에우,에경,finally블록이 계속 실행됩니다.

finally 코만드에 경우에도 됩니다.try 록블returns의

마지막으로 [예외 발생 여부에 관계없이] 모든 조건에서 평가해야 하는 코드를 포함합니다.

마지막 블록을 실행하지 않고는 시도 블록을 종료할 수 없습니다.최종 블록이 존재하는 경우 항상 실행됩니다.(이 진술은 모든 면에서 사실입니다.마지막 블록을 실행하지 않고 시도 블록을 종료하는 방법이 있습니다.코드가 시도 블록 내에서 System.exit(0)을 실행하면 응용 프로그램이 최종 실행되지 않고 종료됩니다.반면, 시도 블록 중에 기계의 플러그를 뽑으면 가 실행되지 않습니다.)

주요 용도는 객체를 폐기하는 것입니다.파일, 열린 리소스(dbstmts)와 같은 사용자 정의 리소스를 닫을 때 유용합니다.

편집

또한 스택 오버플로 예외 후에는 최종적으로 실행되지 않습니다.

데이터베이스 연결을 처리하거나 개체를 폐기해야 할 때 이 방법을 사용하는 것이 좋습니다.쿼리를 실행하는 동안 문제가 발생할 경우에도 연결을 안전하게 닫을 수 있습니다.또한 try/catch/finally 블록 외부의 블록이 액세스할 수 없는 코드를 정리하는 데 도움이 됩니다.

Finally 블록은 예외로 인해 함수가 종료되는지 여부에 관계없이 실행됩니다.(이 규칙에는 몇 가지 예외가 있습니다. 자세한 내용은 이 스택 오버플로 질문을 참조하십시오.)

예:

Try
    'Do something
Catch ex As Exception
    if 'Some Condition
       throw ex
    else
       'Handle exception
Finally
    'Do cleanup
End Try

이 경우 기능에서 예외를 발생시킬 수 있더라도 Finally(최종) 블록은 계속 실행됩니다.

이 방법은 정리 코드가 항상 실행되도록 보장하기 때문에 이 방법을 사용하는 것이 방법은 다음과 같습니다.물론 Resource Acquisition Is Initialization 관용구를 사용하는 것이 리소스를 정리할 수 있는 훨씬 더 깨끗한 방법이지만, VB.net 에 대해서는 잘 알지 못하므로 이러한 작업이 가능한지 여부를 알 수 없습니다.

마지막으로 시스템의 일관성을 유지하기 위해 수행해야 하는 모든 작업에 익숙해야 합니다.이는 일반적으로 리소스를 해제하는 것을 의미합니다.

마지막으로 예외가 발생한 경우에도 항상 실행됩니다.다음과 같은 경우 리소스를 해제하는 데 사용해야 합니다.

  • 연결 완료
  • 파일 처리기 닫기
  • 사용 가능한 메모리
  • 데이터베이스 연결 닫기

완벽한 예를 들어보겠습니다.네트워크를 통해 메시지를 보내고 있다고 상상해 보십시오.유사 코드:

// With finally                  |  //Without finally
try{                             |  try{  
  send_message()                 |    send_message() 
} catch(NetworkError){           |  } catch(NetworkError){ 
  deal_with_exception()          |    deal_with_exception()
} finally {                      |  }
  finalizes_connection()         |  finalizes_connection() 
}                                |

두 코드의 유일한 차이점은 무엇이 다음에서 유지되는지입니다.try은 block이 시킵니다.NetworkError를 들어, , 를들면예,MethodNotFound 번째 은 첫번경우, 은법방입니다.finalizes_connection()호출될 것이고, 두 번째 것에서는 호출되지 않을 것입니다.

연결은 두 개 이상의 프로그램을 통해 자연스럽게 이루어집니다.그럼 어떻게 되는 겁니까?MethodNotFound다른 프로그램에 대한 예외?첫 번째 경우, 당신의 프로그램은 연결을 완료하고 다른 프로그램은 행복할 것입니다.두 번째 경우, 다른 프로그램은 사용자의 응답을 영원히 기다릴 수 있습니다.다른 프로그램이 한 번에 하나의 연결만 수신할 수 있으면 어떻게 합니까?당신은 방금 다른 프로그램도 도청했습니다.

예를 들어 Windows(윈도우)에서 다른 프로그램을 읽기 위해 열 수 없는 경우와 같은 파일에도 적용됩니다.그리고 메모리의 경우, 그것은 결코 해제되지 않고 이제 메모리 누수가 발생합니다.

마지막으로 정리 코드(예: DB 연결 또는 닫아야 하는 파일)에 사용합니다.예외 여부와 관계없이 실행해야 하는 거의 모든 정리 코드

또한 예외 처리 시 예외 또는 기타 예외를 다시 삭제해야 할 수 있습니다. 이 경우 블록 다음 코드가 실행되지 않습니다.

마지막 블록에서 정리를 수행하는 것은 해당 블록이 실행되는지 확인하는 것입니다.캐치 블록이 예외(즉, 예외)를 처리하지 않는 경우).기록하기만 하면 됩니다.) 또는 다른 예외가 발생하더라도 최종 블록의 코드는 계속 실행됩니다.

다른 모든 사람들이 말한 것 외에도, 저는 의미론적으로 그들이 다르다고 생각합니다.

마지막 블록의 코드는 트라이캐치에 포함된 콘텐츠에 대해 최종화 유형 작업을 수행하고 있음을 분명히 나타냅니다.제 생각에 이것은 읽기에 더 명확한 것 같습니다.

제가 기억하는 한, 저는 제 .NET 코드에서 try/catch/finally block을 사용해 본 적이 없습니다.

일반적으로 중간 계층에서 예외를 잡는 것은 거의 필요하지 않습니다.예외는 일반적으로 프레젠테이션 계층의 최상위 처리기에 전파되며, 로그에 기록될 수 있도록 계층 경계에서 포착되어 다시 던져질 수 있습니다.

따라서 중간 계층에서는 리소스를 정리하기 위해 시도/최종(또는 "사용" 문)을 더 자주 볼 수 있습니다.프레젠테이션 계층의 최상위 처리기를 사용해 보십시오.

예외를 발견하고 정리를 수행해야 하는 드문 경우에는 다음과 같이 리팩터링하고 싶습니다.

try
{
    ... do something
}
catch
{
   ... handle exception
}
finally
{
   ... cleanup
}

다음이 됩니다.

try
{
    DoSomethingAndCleanup();
}
catch
{
   ... handle exception
}

...
private void DoSomethingAndCleanup()
{
    try
    {
        ... do something
    }
    finally
    {
        ... cleanup
    }
}

IMHO 이것은 훨씬 깨끗합니다.

시도 캐치 블록을 실행한 후에는 캐치가 실행되지 않습니다.예외가 발생하고 캐치 블록이 해당 유형의 예외를 처리할 수 있는 경우에만 캐치가 실행됩니다.

마지막 블록은 시도 블록이 완료될 때 실행되는 블록입니다.완료되면 정상적으로 종료되거나 어떤 방식으로든 종료됩니다(루프에서 해제, 메서드에서 복귀, 예외 발생 등).

코드를 최종 블록 외부에 배치하고 예외를 던지면(예를 들어) 예외가 포착되지 않거나, 캐치 블록에 다시 던지거나, 새로운 예외가 캐치 블록에 던져지면 코드가 실행되지 않을 수 있습니다.마지막 블록 안에 넣으면 실행됩니다.

기본적으로 청소는 마지막 블록에 넣어야 합니다.

위의 제 댓글에 대한 답변을 읽고 몇 가지 생각이 났습니다.

문제의 코드를 모르면 기본적으로 질문에 완전히 답할 수 없습니다.

그 이유는 모든 코드가 최종적으로 블록에 들어갈 수 없기 때문입니다.예를 들어, 수율 문은 최종적으로 (및 캐치) 블럭에 허용되지 않습니다.시도 블록에는 일부는 반환되고 일부는 반환되지 않는 여러 실행 분기가 있을 수 있습니다.이 모든 경우에 최종적으로 실행되는 반면, 최종적으로 실행되지 않는 예제에서는 정리 코드의 경우가 아닙니다.또한 캐치 블록 이후에 코드로 점프할 수 있는 경우는 매우 드물지만 최종 블록으로 점프(이동)할 수 없습니다.마지막 블록에서 돌아올 수도 없습니다.

대부분의 경우 실제 코드에 따라 답이 달라지는 매우 드문 경우도 꽤 있습니다.

제가 자주 사용하는 것은 다음과 같습니다(이를 하나의 측면으로 캡슐화했지만, 이것이 바로 제가 그 측면을 도출한 것입니다).

public static DoLengthyProcessing(this Control control, Action<Control> action)
{
    Cursor oldCursor = control.Cursor
    try
    {
        control.Cursor = Cursors.WaitCursor;
        action(control);
    }
    catch (Exception ex)
    {
        ErrorHandler.Current.Handler(ex);
    }
    finally
    {
        control.Cursor = oldCursor;
    }
}

또는 (나처럼) AOP를 사용합니다.

언급URL : https://stackoverflow.com/questions/1158667/why-use-finally-in-try-catch