2017-12-28 34 views
-1

는 다음 코드를 실행하고 있습니다 :이 프로그램은 성공적으로 컴파일하고 출력한다체크 예외를 사용하여 체크되지 않은 예외를 throw 할 수 있습니까?

import java.io.FileNotFoundException; 
import java.io.IOException; 

class Basic1 { 
    int c; 

    void calculation(int a, int b) throws Exception { 
     c = a/b; 
    } 
} 

class Basic extends Basic1 { 
    void calculation(int a, int b) throws IOException { 
     c = a/b; 
     RuntimeException ae = new ArithmeticException(); 
     throw ae; 
    } 

    public static void main(String[] args) { 
     int a = 10; 
     int b = 0; 
     int c; 
     Basic ba = new Basic(); 
     try { 
      ba.calculation(a, b); 
     } catch (IOException e) { 
      System.out.println("Zero can't be there in the denominator. : IoException"); 
     } catch (ArithmeticException e) { 
      System.out.println("Zero can't be there in the denominator. : Arthimetic Exception"); 
     } catch (Exception e) { 
      System.out.println("Zero can't be there in the denominator. : Exception"); 
     } 
    } 
} 

"제로는 분모에있을 수 없습니다. Arthimetic 예외"(예상대로 출력됩니다).

제 질문은 프로그램을 어떻게 성공적으로 컴파일 할 수 있습니까? 내부에있는 동안 IOException을 던지면 오류가 발생하지 않습니다. calculation()RuntimeException 개체를 생성하고 있습니까?

두 번째 질문은 프로그램이 catch (ArithmeticException e) 절을 입력한다는 것입니다. 컴파일러는 실행시에 catch을 실행할 것을 결정합니까? 나는 정확하게 이해합니까?

+1

throws 절에서 RuntimeException을 선언 할 필요가 없습니다. – tsolakp

+1

"RunTimeException 클래스의 객체를 생성하는 동안 IoException을 던지고있는 중 오류가 발생하지 않는 이유는 무엇입니까?"이 문장의 의미는 무엇입니까? –

답변

0

첫 번째 질문의 경우 throws E (여기서 E은 임의로 검사 된 예외 임) 구문을 사용하는 방법은 아무 것도 던지지 않아도됩니다. 즉, 메서드를 호출하는 모든 사람이 E을 처리 할 수 ​​있어야합니다.이 메서드는 처리하지 않고 E을 던져 버릴 수 있습니다. 그렇지 않으면 컴파일 오류가 발생합니다. 일반적으로 메서드 설명서에 E이 던져 질 때 지정됩니다. JLS의 말 : 각각의 방법 또는 생성자의 몸체의 실행 결과 수 예외 체크 위해

본질적으로, 컴파일 시간 오류는 예외 타입 또는 예외 형태의 슈퍼 않는 발생 메소드 또는 생성자 선언의 throws 절에서 언급됩니다.

이렇게하면 메서드 본문 내에 주어진 검사 예외를 throw해야한다고 말하지는 않습니다. 검사되지 않은 예외가있는 throws을 사용할 수는 있지만 프로그램에 영향을주지는 않습니다. 검사되지 않은 예외가 처리되지 않는 곳이면 어디든지 던져 질 수 있기 때문입니다. 그것이 그들의 핵심입니다.

코드에서 RuntimeException을 던집니다. RuntimeException (그 자체 포함)을 확장하는 모든 클래스는 정의에 의해 선택 해제됩니다. ArithmeticException이 하나이므로 RuntimeException 유형의 변수에 할당 한 다음 throws 절에 지정하지 않고 예외를 던질 수 있습니다.

두 번째 질문에 대해서는 컴파일러가 다양한 catch 절을 최적화하지 않는다고 가정합니다. 이 경우 아니요, 실행되는 catch은 컴파일 타임에 결정되지 않습니다. 프로그램에 예외가 발생하면 예외가 잡힐 때까지 스택에 전파됩니다. 그렇지 않으면 실행을 중지하고 스택 추적은 System.err에 인쇄됩니다. ArithmeticException이 던져지기 때문에 첫 번째 catch 절은 일치하지 않지만 두 번째 것은 수행되므로 실행됩니다. 세 번째 항목 (catch (Exception e))은 일치하지만 catch 절로 주문이 중요하며 하나만 실행되므로이 ​​절은 여기에서 실행되지 않습니다. 컴파일러는 당신의 catch 절을 멀리 최적화하고 바로 catch (ArithmeticException e) 절에 코드 프로그램을 지시하는 것이 당신의 방법은 항상 ArithmeticException를 슬로우로

그러나,이 경우, 상상할 수 없습니다. 그러나 어떤 코드 행이라도 애매한 오류가 발생할 수 있습니다 (예 : OutOfMemoryError). 컴파일러는 최적화 할 때 이러한 엣지 케이스를 허용해야합니다.