함수를 호출 할 때 "예외 발생"이 필요한 이유는 무엇입니까?


98
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

왜 컴파일러보고하는 방법 show2(), show3()main()

보고되지 않은 예외 잡히거나 던지기 위해 선언해야하는 예외

throws Exception이 방법에서 제거하면 ?


2
@PaulTomblin main은 확실히 Exception을 던지도록 선언 할 수 있습니다. 그렇다면 JVM이 종료됩니다. 이것은 컴파일러가 허용하는 한 무시하는 것과 비슷합니다.
Taymon

호출 방법 (때 Methdod1가 ) 발생 Exception, 우리는 호출 방법 (정의해야합니다 방법 2 과를) throws Exception; 호출 메서드에서 해당 예외를 처리하지 않는 경우. 이것의 목적은 호출 방법 (에 머리를 포기하는 것입니다 의 Method3 의) 방법 2 예외에 의해 발생 될 수 있음을 방법 2 와 다른이 프로그램을 중단 할 수있다, 여기를 처리해야합니다.
Rito

마찬가지로 Method3 이 본문에서 예외를 처리하지 않는 경우 throws Exception호출 메서드를 헤드에 제공하기 위해 메서드 정의에서 정의해야합니다. 이전 주석의 확장
Rito

답변:


144

아시다시피 Java에서 예외는 두 가지로 분류 할 수 있습니다. 하나는 throws절이 필요 하거나 하나는 지정하지 않으면 처리해야하고 다른 하나는 지정하지 않으면 처리해야합니다. 이제 다음 그림을 참조하십시오.

여기에 이미지 설명 입력

Java에서는 Throwable클래스 를 확장하는 모든 것을 던질 수 있습니다 . 그러나 throws모든 클래스에 대해 절 을 지정할 필요는 없습니다 . 특히이 두 가지의 하위 클래스 중 하나 Error또는 하나 인 RuntimeException클래스입니다. 귀하의 경우 Exception에는 Error또는 의 하위 클래스가 아닙니다 RuntimeException. 따라서 검사 된 예외이며 throws특정 예외를 처리하지 않는 경우 절에 지정되어야합니다 . 그렇기 때문에 throws조항 이 필요했습니다 .


에서 자바 튜토리얼 :

예외는 프로그램 실행 중에 발생하는 이벤트로, 프로그램 명령의 정상적인 흐름을 방해합니다.

이제 아시다시피 예외는 선택 및 선택 취소의 두 가지로 분류됩니다. 왜 이러한 분류입니까?

확인 된 예외 : 프로그램 실행 중에 복구 할 수있는 문제를 나타내는 데 사용됩니다. 일반적으로 프로그래머의 잘못이 아닙니다. 예를 들어 사용자가 지정한 파일을 읽을 수 없거나 사용할 수있는 네트워크 연결이 없습니다. 이러한 모든 경우에 프로그램을 종료 할 필요가 없습니다. 대신 사용자에게 경고하는 것과 같은 조치를 취하거나 대체로 이동할 수 있습니다. 메커니즘 (네트워크를 사용할 수없는 경우 오프라인 작업과 같은) 등

확인되지 않은 예외 : 다시 오류와 런타임 예외의 두 가지로 나눌 수 있습니다. 그것들이 확인되지 않는 한 가지 이유는 그것들이 수적으로 많고, 그것들을 모두 처리해야하기 때문에 우리 프로그램을 복잡하게 만들고 명확성을 떨어 뜨릴 것입니다. 다른 이유는 다음과 같습니다.

  • 런타임 예외 : 일반적으로 프로그래머의 오류로 인해 발생합니다. 예를 들어 ArithmeticException0으로 나누기 또는이 ArrayIndexOutOfBoundsException발생하면 코딩에 충분히주의하지 않았기 때문입니다. 일반적으로 프로그램 로직의 일부 오류 때문에 발생합니다. 따라서 프로그램이 프로덕션 모드로 들어가기 전에 지워야합니다. 프로그램이 발생하면 프로그램이 실패해야한다는 의미에서 확인되지 않았으므로 프로그래머가 개발 및 테스트시 문제를 해결할 수 있습니다.

  • 오류 : 오류는 일반적으로 프로그램이 복구 할 수없는 상황입니다. 예를 들어, a StackOverflowError가 발생 하면 프로그램의 함수 호출 스택 크기를 늘리는 등 많은 일을 할 수 없습니다. 또는 발생하는 OutOfMemoryError경우 프로그램에서 사용할 수있는 RAM의 양을 늘리기 위해 많은 일을 할 수 없습니다. 이러한 경우 프로그램을 종료하는 것이 좋습니다. 그것이 그들이 확인되지 않은 이유입니다.

자세한 내용은 다음을 참조하십시오.


내가 당신의 대답에서 얻은 것은 Error 클래스와 그 하위 클래스 및 RuntimeException 클래스와 하위 클래스가 확인되지 않은 예외 (System.out.println (5/0)와 같은) 아래에 있다는 것입니다. 런타임 예외이지만 여전히 try catch를 적용 할 수 있음) 예외 클래스가 검사되므로 해당 메서드와이를 호출하는 모든 메서드에서 throws 절을 선언해야합니다.
nr5

한 가지 더 질문 : 예외가 검사되지 않은 것으로 분류되고 검사 된 경우, 특히 컴파일 시간 동안 더 많은 오류를 방지하기 위해 검사되지 않은 항목 (런타임 오류)이 있습니까?
nr5

@Jomoos-메서드 내부의 코드에서 IOException이 발생한다고 가정합니다. 그러면 메서드의 선언에 "throws Exception"을 넣어도 괜찮습니까?
MasterJoe

오. 이제 이해가된다. 예외 계층 구조의 규칙에는 예외가 있습니다. 만든다. 완전한. 감각. 감사합니다 Java.
JJS

25

Java에서는 모든 예외를 처리하거나 선언해야합니다. try / catch 블록을 사용하여 Exception을 처리하지 않는 경우 메서드의 서명에서 선언해야합니다.

예를 들면 :

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

다음과 같이 작성해야합니다.

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

이렇게하면 메서드 선언에서 "throws Exception"선언을 제거 할 수 있습니다.


7
의 하위 클래스가 아닌 모든 예외 RuntimeException, 즉.
yshavit

체크 된 Exception과 같은 다른 클래스가 있다면?
nr5

1
무슨 말이야? 모든 예외 객체는 기본 클래스로 "Exception"을 가지고 있기 때문에 "Exception"객체를 포착하면 (예제에서와 같이) throw되는 모든 예외를 포착합니다. 좀 더 구체적으로 말하자면 (다른 예외는 아마도 다른 처리 방법을 필요로 할 것이기 때문에) 여러 catch 블록이 있어야합니다.
jebar8

확인 된 예외가 @ 컴파일 시간에 처리되고 런타임에 포착되어야한다고 말하면. 내가 맞아? 그렇다면 확인되지 않은 예외에 대해 동일한 문장을 표현하면 될까요?
nr5

@ jebar8-Java와 .NET을 혼동하고 있습니다. Java에서 throwables는 상속해야합니다 Throwable(상속 Exception도. 확장되기 때문에 작동 Throwable하지만 필수는 아님).
BrainSlugs83

5

throws Exception선언은 예상하지만, 어쩔 수없는 이유에 대한 예외를 던질 수있는 방법을 추적하는 자동화 된 방법입니다. 선언은 같은 발생 될 수 있습니다 예외의 종류 나 유형에 대한 일반적으로 특정 throws IOException또는 throws IOException, MyException.

우리 모두는 예기치 않게 중지하고 0으로 나누기 또는 범위를 벗어난 인덱스와 같이 프로그램을 실행하기 전에 예상하지 못한 예외로 인해 예외를보고하는 코드를 가지고 있거나 결국 작성할 것입니다. 메서드에서 오류가 예상되지 않았기 때문에 오류를 "잡을"수 없으며 try catch 절로 처리 할 수 ​​없습니다. 이 방법의 의심하지 않는 사용자도이 가능성을 모르고 프로그램도 중지됩니다.

프로그래머가 특정 유형의 오류가 발생할 수 있음을 알고 있지만 메서드 외부에서 이러한 예외를 처리하려는 경우 메서드는 하나 이상의 예외 유형을 처리하는 대신 호출하는 메서드에 "스로"할 수 있습니다. 프로그래머가 메소드가 예외를 던질 수 있다고 선언하지 않은 경우 (또는 Java가이를 선언 할 수없는 경우) 컴파일러는 알 수 없으며 알 수있는 메소드의 향후 사용자가 결정할 수 있습니다. 메소드가 던질 수있는 모든 예외를 포착하고 처리합니다. 프로그램은 여러 다른 프로그램에 의해 작성된 여러 계층의 메서드를 가질 수 있으므로 어떤 메서드가 예외를 throw 할 수 있는지 추적하는 것이 어렵습니다 (불가능).

Java에는 예외를 선언 할 수있는 기능이 있지만 여전히 처리되지 않은 예외와 선언되지 않은 예외가있는 새 메서드를 작성할 수 있으며 Java는이를 컴파일하고 실행할 수 있으며 최선을 다할 수 있습니다. Java가 허용하지 않는 것은 메서드에서 선언 된 예외를 처리하거나 메서드가 동일한 것을 던지는 것으로 선언하지 않는 한 예외를 throw하는 것으로 선언 된 메서드를 사용하는 경우 새 메서드를 컴파일하는 것입니다. 예외 또는 여러 예외가있는 경우 일부를 처리하고 나머지를 throw 할 수 있습니다.

프로그래머가 메서드가 특정 유형의 예외를 throw한다고 선언하면 예외가 가능하다는 메서드를 사용하여 다른 프로그래머에게 경고하는 자동화 된 방법 일뿐입니다. 그런 다음 프로그래머는 동일한 예외를 throw하는 호출 메서드를 선언하여 예외를 처리하거나 경고를 전달할 수 있습니다. 컴파일러는이 새 메서드에서 예외가 가능하다는 경고를 받았으므로 새 메서드의 향후 호출자가 예외를 처리하는지 선언하고 둘 중 하나가 발생하도록 강제 할 수 있는지 자동으로 확인할 수 있습니다.

이 유형의 솔루션에 대한 좋은 점은 컴파일러가보고 Error: Unhandled exception type java.io.IOException할 때 예외를 발생시키기 위해 선언 된 메서드의 파일과 줄 번호를 제공한다는 것입니다. 그런 다음 단순히 벅을 전달하고 메서드를 "throws IOException"으로 선언하도록 선택할 수 있습니다. 이것은 프로그램이 중지되고 사용자에게 예외를보고하도록하는 주요 메소드까지 수행 할 수 있습니다. 그러나 예외를 포착하고 사용자에게 발생한 일과 수정 방법을 설명하는 것과 같은 좋은 방식으로 처리하는 것이 좋습니다. 메서드가 예외를 포착하고 처리 할 때 더 이상 예외를 선언 할 필요가 없습니다. 벅은 말하자면 거기서 멈춘다.


4

Exception확인 된 예외 클래스입니다. 따라서이를 throws Exception처리하거나 선언해야 한다고 선언하는 메서드를 호출하는 모든 코드입니다 .


체인의 모든 메서드는 main을 포함하여 Exception을 throw하도록 선언됩니다. 그렇다면 문제는 어디입니까?
Paul Tomblin 2012

@PaulTomblin IM은 왜 호출 함수에서 예외를 발생
시키는데

좋아, 게시 한 코드에서 실제로 얻지 못한 컴파일러 오류에 대해 왜 묻는 지 이해하지 못했습니다. 그것은 이상한 질문 방법입니다.
Paul Tomblin

0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

프로그램의 작은 변화. 주요 이슈와 관련하여 많은 사람들이 오해하는 것처럼 보이는 것은 예외를 던질 때마다 처리해야하며 같은 장소 (예 : 프로그램의 show1,2,3 메서드)에서 필요하지 않지만 처음에는 호출자 메서드에서 처리해야한다는 것입니다. '메인'내부. 한마디로 'throw'가 있고, 예외가 발생하는 동일한 방법이 아니더라도 'catch / try'가 있어야합니다.


0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

show () method에 확인 된 예외가 있으므로 해당 메서드에서 처리되지 않는 예외가 있으므로 예외를 전파하기 위해 throws 키워드를 사용합니다.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

show2 () 메서드에서 show () 메서드를 사용하고 있고 예외를 최소한 전파 했으므로 여기서 처리해야합니다. 여기서 Exception을 처리하지 않는 경우 throws 키워드를 사용하고 있습니다. 이것이 메소드 서명에서 throws 키워드를 사용하는 이유입니다.


0

현재 메서드의 시그니처에서 throws 지시문을 선언하여 예외를 전파하는 경우 라인 또는 호출 스택의 어딘가에서 예외를 처리하기 위해 try / catch 구문을 사용해야합니다.


이 의견은 검증 가능한 답변이나 예를 제공하지 않으므로 의견 섹션에 추가해야합니다. - stackoverflow.com/help/how-to-answer
폴 도슨

-1

기본적으로 예외를 던지는 것과 같은 위치에서 예외를 처리하지 않는 경우 함수 정의에서 "예외 발생"을 사용할 수 있습니다.

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