2013-03-26 2 views
4

예외가 호출 스택 위로 전파되는 개념 또는 실제로 유용함을 이해하는 데 어려움을 겪고 있습니다. 나는 그것들을 만드는 방법을 얻었지만, 수학이나 뭔가를위한 간단한 실세계 응용에서와 같이, 언제 사용되는지를 정말로 알지 못합니다.예외가 전파 됨 호출 스택

public void method1(){ 
    try{ 
     method2(); 
    } 
    catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

public void method2(){ 
     try{ 
      throw new Exception(); 
     } 
     finally{ 
     System.out.println("no exception, try cleanup"); 
     } 
} 

나는 이것이 아마 많은 예외와 기능을 더 복잡 할 것이지만 그것이 작동,하지만 난 정말 모든에 어획량이를 사용하는 대신에 단지있는의 요점을 파악하지 않는 방법 기본적 것을 얻을 기능.

+1

모든 함수에서 catch가 ** Excecptions **를 숨기기 때문에 이것은 일반적인 "ick 코드"실수입니다. 예외를 처리하지 않으려면 * catch하지 마십시오. 그렇지 않으면 그것을 처리하지 않고 그냥 로그하기를 원한다면 * 예외를 다시 던지십시오. –

답변

3

...하지만 모든 기능에 걸리는 대신에 이러한 점을 실제로 사용하지는 않습니다.

요점은 호출 스택의 다음 함수가 예외 처리 방법을 알지 못한다는 것입니다. 예 :

public class Test { 

    public Object doSomething(String source) throws IOException { 
     try (InputStream is = openAsStream(source)) { 
      // ... read and process stuff 
      return ... 
     } 
    } 

    public InputStream openAsStream(String name) throws IOException { 
     String fileName = // ... do something with 'name' 
     return new FileInputStream(name); 
    } 

    public static void main(String[] args) { 
     // ... 
     Test t = new Test(); 
     try { 
      t.doSomething(args[0]); 
     } catch (IOException ex) { 
      System.err.println("Cannot handle '" + args[0] + "'"); 
     } 
    } 
} 

openAsStreamIOException을 던질 수있는 FileInputStream 생성자를 호출합니다. openAsStream 메서드는이를 복구 할 수 없으므로이를 전파 할 수 있습니다. doSomething 메서드는이 메서드를 처리하는 방법을 알지 못하기 때문에 전파 할 수 있습니다. 마지막으로 예외는 main ... 사용자에게 문제를 설명하는 방법을 알고 있습니다.


이제 당신은 IOException를 잡을 오류 메시지를 인쇄하고 null을 반환 openAsStream을 작성할 수 있습니다. 그러나 그것은 큰 실수가 될 것입니다 :

  • openAsStream()하지 않습니다 (그리고 해야하지)하는 방법을 사용자에게 문제를보고/여부를 알 수 있습니다.

  • 그리고 null을 호출자에게 반환하면 호출자는 호출 결과가 null ...인지 확인하고 다른 조치를 취해야합니다.

요점은 메서드가 해당 수준에서 적절히 처리 할 수있는 예외 만 처리해야한다는 것입니다. 다른 사람들은 전파가 허용되어야합니다. (또는 API 디자인에 필요한 경우 또 다른 예외가 적용됩니다.)

1

경우에 따라 예외를 생성하는 코드는 올바르게 처리하는 방법을 알 수 없습니다. 트랜잭션 코드에서 뭔가가 터지면 해당 메소드/구성 요소는 처리하려고 시도하면 예외를 기록하는 것 이상의 기능을 수행하지 못할 수 있습니다. 반면에 하나 이상의 레이어가 있으면 연결을 다시 설정하거나 요청자에게 자세한 오류 응답을 제공 할 수 있습니다.

+0

또는 "올바르게 죽습니다". –

+0

예외가 발생하는 함수가 예외를 처리 할 수 ​​없다는 것이 이상한 부분이라고 생각합니다. – sl133

+0

@ sl133 'DbConnection connect (String dbConnStr)'와 같은 함수가 데이터베이스에 연결을 시도했지만 연결이 거부되었으므로 예외가 있다고 가정 해보십시오. 이 함수는 보통 데이터베이스 연결을 반환합니다.이 "예외적 인 상황"이 발생하면 어떻게해야합니까? –

1

예외를 생성하는 동작을 수행하는 코드가 그렇지 않은 경우 문제를 처리 할 적절한 컨텍스트를 호출자가 종종 가지는 경우가 많습니다. 필자는 파일에 데이터를 쓰고 싶은 고수준 프로그램이라고 가정 해 보겠습니다. 필자가 호출하는 저수준 서비스는 writeFile()이 다양한 이유로 IOException을 throw 할 수 있다고 가정합시다.

writeFile()을 작성한 사람은 writeFile()이 사용될 컨텍스트에 대해 알지 못합니다. writeFile()이 실패하면 파일을 다시 써야합니까? 몇 번이나 시도해야합니까? 그냥 포기해야할까요? 일부 작업을 수행하는 계획에서 writeFile()의 하위 레벨 함수 writeFile()의 컨텍스트를 작성한 프로그래머는 잡초에서 너무 멀리 떨어져 있기 때문에 프로그래머는 호출자가 오류 조건을 처리하는 방법을 예상하지 못할 수 있습니다.

발신자가 오류를 처리하는 방법을 추측하는 대신 (불가능한 작업 임) writeFile() 프로그래머는 writeFile()을 호출하는 클라이언트에게 "열린 질문"이 필요함을 나타냅니다 문제가 생겼을 때 대답하십시오. 각 문제는 예외 클래스에 의해 표시되며 클라이언트 프로그래머가 예외를 잡으면 클라이언트 프로그래머는 클라이언트 프로그래머가 가질 수없는 상황과 함께 열린 질문에 대한 응답을 작성합니다.

즉, 확인 된 예외를 나열하는 메서드를 본 적이없는 경우 해당 예외를 작성한 프로그래머는 "이 메서드를 호출하면 적합한 예외 상황을 처리하기위한 적절한 컨텍스트가 만들어집니다. 하지 마라."

+0

그래서 writeFile()은 IOException을 잡아서 다시 던질 것인가? 또는 writeFile()에 try catch가 있으면 부모는 그 예외를 어떻게 잡을까요? – sl133

+0

Java에서 각 메소드는 throw 할 수있는 Checked 예외의 유형을 선언합니다. 예를 들어, writeFile()의 프로그래머는 그의 메소드 선언을 쓸 것입니다. void writeFile() throw IOEException {CODE HERE ...} 그리고 CODE HERE 섹션의 어딘가에서 writeFile()의 프로그래머가 IF (FOO == BAR)를 호출 한 다음 true가 아니면 예외를 throw합니다. throw new IOException();} – Jazzepi

+0

writeFile()은 매우 낮은 수준이므로 실제로 예외를 만든 다음이를 처리 할 호출 클라이언트에 전달합니다. 이는 의도적으로 설계된 동작입니다. 이 기록은 실제로 꽤 좋습니다. http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html – Jazzepi

1

예외 전파는 코드가 오류로 인해 기본적으로 오류가 발생하도록 만듭니다.

예외 전파에 대한 대체 접근법을 고려해보십시오. 오류 코드가 반환됩니다. 실수로 또는 의도적으로 코드에 대한 호출자가 오류 코드를 테스트하지 않으면 메서드가 사용 가능한 상태가 아니며 메서드를 계속 호출하여 정의되지 않은 동작/메모리 손상을 유발할 수 있습니다. 대신 예외를 던지면 호출자가 예외를 잡는 것을 잊어 버리고 끔찍한 일을하는 대신 빨리 실패하고 프로그래머에게 던져진 곳에 대해 왜, 어떻게해야할지 경고 할 수 있습니다. 예외는 크게 이 필요하다는 조건을 나타 내기 때문에 크게 불쾌합니다.