2010-12-09 2 views
1

오류가 발생하면 트리거 할 코드가 필요합니다. 기본적으로 예외의 경우에만 실행되는 finally 블록이 필요합니다.Java에서 오류 케이스에 대해 'finally'를 구현하는 방법

HttpURLConnection post(URL url, byte[] body) throws IOException { 
    HttpURLConnection connection = url.openConnection(); 
    try { 
     OutputStream out = connection.getOutputStream(); 
     try { 
      out.write(body); 
     } finally { 
      out.close(); 
     } 
     return connection; 
    } catch (Throwable t) { 
     connection.disconnect(); 
     throw t; 
    } 
} 

미세 제외 보이는이 컴파일되지 않습니다 : 내 기능은 Throwable을 던질 수 없습니다 나는이 방법을 구현하는 것입니다.

내가 쓰기 다시 수 :

} catch (RuntimeException e) { 
     connection.disconnect(); 
     throw e; 
    } catch (IOException e) { 
     connection.disconnect(); 
     throw e; 
    } 

하지만 그렇다하더라도 난 A) 모든 오류 누락와 b)이 코드를 내가 예외의 다른 유형을 던져 내 구현을 변경할 때 시간을 수정해야합니다.

일반적으로이 문제를 해결할 수 있습니까?

+4

예외는 확인되지 않았습니다. * 환상적입니까? * – cdhowie

+0

@cdhowie : 나는 또한 예외 검사를 싫어하지만 실제로 이것은 오류 및 Throwable이 검사되지만 검사되지는 않습니다. 런타임의 아무 것도 "throw XxxError"를 선언하지 않지만 갑자기 XxxError를 던지려고하면 HUH가 표시됩니까? 그게 뭐야? 체크 된 예외는 Throwable의 추상 서브 클래스 인 CheckedException으로 수행되어야합니다.이 서브 클래스는 현재 "마법"이 아닌 컴파일러에 의해 검사됩니다. 물론 체크 예외를 Throwable로 다시 발생시킬 수는 있지만, 그렇게 확신 할 수는 없습니다. 나쁜 것. –

+0

@ Software Monkey : 실제로'Error'는 체크되지 않습니다. 방금 체크했습니다. :)'throws' 절에서 언급하지 않고'Error'를 잡아서 다시 던질 수 있습니다.그것은 내 솔루션에 또 다른 경우를 추가 할 것이기 때문에 유지 보수가 훨씬 쉽지 않습니다. 현실은'CheckedException' 대신에 Java가'RuntimeException'과'Error'라는 두 개의 확인되지 않은 나무를 가지고 있습니다. 다른 모든 것들은 검사됩니다. – SnakE

답변

11

finally 블록을 사용하고 성공을 나타내는 플래그를 추가 할 수 있습니다.

bool success = false; 
try { 
    //your code 
    success = true; 
    return retVal; 
} finally { 
    if (!success) { 
     //clean up 
    } 
} 
+0

이것은 확실히 예외 유형 목록보다 훨씬 낫습니다. 지금 당장은이 솔루션을 고집 할 것입니다. 언어 구조가 아닌 것은 나쁘지 않습니다. – SnakE

3

Throwable는 두 개의 서브 클래스, ErrorException 있습니다. Error에 대한 Javadoc과 말 : 가 의 어플리케이션으로을 잡으려고 을 시도해서는 안되는 심각한 문제를 나타내는 것을

오류가의 Throwable 의 서브 클래스입니다. 대부분의 이러한 오류는 비정상적인 조건입니다. ThreadDeath 오류는 "정상"조건이지만 대부분 응용 프로그램이 을 잡아서는 안되기 때문에 오류의 하위 클래스이기도합니다. 이것은 정말 이상한 situtation 경우를 제외하고

그래서, 당신은 단지 Exception에 초점을 맞출 수 있습니다 : 내가 잘못 생각하지 않는 예외가 실행을 중지하고 당신이 필요로하는 일을 할 수있는 finally 블록을 필요로하지 않을

catch (IOException e) { 
    connection.disconnect(); 
    throw e; 
} 
catch (RuntimeException e) { 
    connection.disconnect(); 
    throw e; 
} 
catch (Exception e) { 
    connection.disconnect(); 
    throw new IOException(e); 
} 
+0

오직 IOException을 던지기 위해 업데이트 됨 –

+0

IOException의 모든 것을 감싸는 것이 나에게 좋은 생각이 아닙니다. 모든 ArrayOutOfBounds는 이런 방식으로 IO로 끝납니다. 오류가 예외보다 더 낫다는 것은 맞지만, 예외 유형을 변경하지 않고 모든 것에 대해 'finally'블록이 투명하게 작동합니다. 가능한 한이 동작을 복제하고 싶습니다. – SnakE

+0

@SnakE - 'finally'기법은 IOException (및 RuntimeException과 다른 예외 유형을 허용하지 않지만 RuntimeException을 자체 블록으로 끌어 올 수 있기 때문에)을 감싸지 않아도됩니다. 다른 예외 유형을 지원할 필요가 없다면 제 예제에서 일반적인 'Exception' 블록을 삭제할 수 있습니다. –

-1

, 정리 또는 오류 완화와 유사합니다.

try { 
    // Do some work! 
    // Fail 
} catch (IOException e) { 
    // Clean up, alert user, expected error 
} catch (Exception e) { 
    // Not so much expected, but lets try to handle this 
} 

오류는 기본적으로 사용자의 아이디어 인 구현 된 클래스 및 메소드에서 발생해야합니다. 실행의 흐름과 오류 전파에 대해 생각해보십시오. 위의 메서드가 특정 예외를 catch하지 않으면 호출 된 모든 것이 예외를 볼 수 있습니다.

Throwable은 서브 클래스가있는 최상위 클래스입니다. 예외는 일반적으로 모두를 잡습니다. 또한 예외 처리를 구현하여 작업을 처리 할 수 ​​있음을 기억하십시오.

관련 문제