Java 메서드 선언에서 throw를 사용하는 경우


82

그래서 저는 Java에서 예외 처리에 대한 기본적인 이해가 좋다고 생각했지만 최근에 약간의 혼란과 의구심을 불러 일으키는 코드를 읽고있었습니다. 내가 여기서 다루고 싶은 가장 큰 의심은 사람이 다음과 같은 Java 메서드 선언을 언제 사용해야 하는가하는 것입니다.

    public void method() throws SomeException
    {
         // method body here
    }

비슷한 게시물을 읽음으로써 throws 는 메서드 실행 중에 SomeException 이 throw 될 수 있다는 일종의 선언으로 사용됩니다 .

내 혼란은 다음과 같은 코드에서 비롯됩니다.

     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

이 예제에서 던지기 를 사용하려는 이유가 있습니까? IOException과 같은 기본적인 예외 처리를 수행하는 경우 단순히 try / catch 블록이 필요합니다.

답변:


79

예외 유형을 포착하는 경우 다시 던지지 않는 한이를 던질 필요가 없습니다. 게시하는 예제에서 개발자는 둘 다가 아닌 둘 중 하나를 수행해야합니다.

일반적으로 예외에 대해 아무것도하지 않으려는 경우 포착해서는 안됩니다.

당신이 할 수있는 가장 위험한 일은 예외를 잡아서 아무것도하지 않는 것입니다.

예외를 던지는 것이 적절한시기에 대한 좋은 논의는 여기에 있습니다.

언제 예외가 발생합니까?


2
검사되지 않은 예외는 'throws'와 함께 메소드 서명에서도 선언되어야합니까? 아니면 검사 된 예외에만 'throws'를 사용하는 것이 관행입니까?
Cody

이 답변은 throws키워드 의 사용이라는 질문의 핵심 측면을 직접적으로 다루지 않습니다 .
Brent Bradburn

@hvgotcodes 예외를 포착하고 아무것도하지 않으면 어떻게됩니까?
Manoj

@manoj 당신은 중요한 정보가 손실되어 일이 깨지고 그것을 알아낼 수 없을 위험이 있습니다. 예외를 포착하고 아무것도하지 않아도되는 경우 (반드시 자바는 아님)가 있지만 문서화해야합니다. 예를 들어, javascript에서 브라우저에 따라 존재하지 않을 수있는 기능을 호출 할 수 있습니다. 주의가 필요한 오류는 아닙니다.
hvgotcodes

22

메서드가 확인 된 예외를 throw하는 경우 메서드에 throws 절을 포함하기 만하면됩니다. 메서드가 런타임 예외를 throw하면 그렇게 할 필요가 없습니다.

확인 된 예외와 확인되지 않은 예외에 대한 배경 정보는 다음을 참조하십시오 . http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

메서드가 예외를 포착하고 내부적으로 처리하는 경우 (두 번째 예제에서와 같이) throws 절을 포함 할 필요가 없습니다.


9

당신이 본 코드는 이상적이지 않습니다. 다음 중 하나를 수행해야합니다.

  1. 예외를 잡아서 처리하십시오. 이 경우 throws불필요합니다.

  2. 제거 try/catch; 이 경우 Exception은 호출 메서드에 의해 처리됩니다.

  3. 예외를 포착하고, 가능하면 몇 가지 작업을 수행 한 다음 예외를 다시 발생시킵니다 (메시지뿐만 아니라)


2

당신이 맞습니다. 그 예에서는 throws불필요합니다. 이전 구현에서 남겨졌을 가능성이 있습니다. 아마도 예외가 catch 블록에서 잡히지 않고 원래 던져졌을 것입니다.


2

게시 한 코드가 잘못되었습니다. IOException을 처리하기 위해 특정 예외를 포착하지만 포착되지 않은 예외를 던지는 경우 예외가 발생해야합니다.

다음과 같은 것 :

public void method() throws Exception{
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println(e.getMessage());
   }
}

또는

public void method(){
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println("Catching IOException");
           System.out.println(e.getMessage());
   }catch(Exception e){
           System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc.");
           System.out.println(e.getMessage());
   }

}


1

제공 한 예제에서 메서드는 IOException을 throw하지 않으므로 선언이 잘못되었습니다 (그러나 유효 함). 내 생각 엔 원래 메서드가 IOException을 던졌지 만 예외를 처리하도록 업데이트되었지만 선언이 변경되지 않았습니다.


1

이것은 대답이 아니라 주석이지만 형식화 된 코드로 주석을 작성할 수 없으므로 여기에 주석이 있습니다.

있다고 가정 해 봅시다

public static void main(String[] args) {
  try {
    // do nothing or throw a RuntimeException
    throw new RuntimeException("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

출력은

test
Exception in thread "main" java.lang.RuntimeException: test
    at MyClass.main(MyClass.java:10)

이 메서드는 "throws"예외를 선언하지 않지만 throw합니다! 트릭은 throw 된 예외가 메서드에서 선언 할 필요가없는 RuntimeExceptions (선택 취소)라는 것입니다. 그녀가 보는 모든 것이 "throw e"이기 때문에이 방법의 독자에게는 약간 오해의 소지가 있습니다. 문이지만 throws 예외 선언이 없습니다.

이제 우리가 가지고 있다면

public static void main(String[] args) throws Exception {
  try {
    throw new Exception("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

메소드에서 "throws"예외를 선언해야합니다. 그렇지 않으면 컴파일러 오류가 발생합니다.


컴파일러는의 throws필요 여부를 결정하기 위해 놀랍도록 정교한 정적 분석을 수행 합니다.
Brent Bradburn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.