-
예외(Exception)
- 우리가 예상한, 혹은 예상치 못한 일이 발생하는 것을 미리 예견하고 안전장치를 하는 것
- 컴파일은 되지만 실행할 때 오류가 난다.
- try~catch문
- try 뒤에 중괄호로 예외가 발생하는 문장들을 묶어 주고, catch 괄호 안에 예외가 발생했을 때 처리를 해준다.
- try 블록 안에서 예외 발생되면 그 뒤 문장은 실행되지 않고 catch블록으로 넘어간다.
- try 블록 안에서 예외가 발생하지 않으면 try 내에 모든 문장이 실행되고 try-catch문장 이후의 내용이 실행된다.
- catch블록은 여러 개 작성해도 된다
- catch블록은 순서가 매우 중요하다.
- catch문장에서 사용할 변수는 try앞에 미리 선언해 놓는다.
try문 안에 선언되어 있으면 사용할 수 없다.
- try~catch~finally
- finally : 어떠한 경우에도 반드시 실행해야 하는 코드 블록
- 모든 예외의 부모 클래스는 java.lang.Exception 클래스다.
- 가장 마지막 catch블록에 Exception클래스를 catch하는 것을 권장한다.
catch 블록 중 발생한 예외와 관련있는 블록이 없으면, 예외가 발생되면서 해당 쓰레드는 끝난다. 따라서, 마지막 catch블록에는 Exception 클래스로 묶어주는 버릇을 들여 놓아야 안전한 프로그램이 될 수 있다.
public void multicatch(){
int[] intArray = new int[5];
try{
System.out.println(intArray[5]);
} catch (ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsException occurred");
} catch (Exception e){
System.out.println(intArray.length);
}
}
출력
ArrayIndexOutOfBoundsException occurred
-
위 예제에서 두 개의 catch문 순서를 바꾸면 컴파일 에러 발생.
Exception 클래스는 모든 클래스의 부모 클래스이고, ArrayIndexOutOfBoundsException 클래스는 Exception 클래스의 자식 클래스이기 때문이다. 부모 예외 클래스가 이미 catch하고, 자식 클래스가 그 아래에서 catch하도록 되어 있을 경우 자식 클래스가 예외를 처리할 수 없어 컴파일 에러가 발생한다.
-
예외의 종류
-
Exception과 Error 클래스는 java.lang.Throwable클래스를 상속 받는다 그래서 Exception이나 Error를 처리할 때 Throwable로 처리해도 무관하다.
이렇게 상속 관계가 되어 있는 이유는 Exception, Error 클래스는 성격은 다르지만 동일한 이름의 메소드를 사용하여 처리할 수 있기 위함
- Throwable
- Throwable()
- Throwable(String message)
- Throwable(String message, Throwable cause)
- 예외 메시지, 예외의 원인인 Throwable 객체
- Throwable(Throwable cause)
- Throwable 클래스에 선언되어 있고, Exception 클래스에서 Overriding한 메소드 중 가장 많이 사용하는 몇몇 메소드
- getMessage()
- 예외 메시지를 String 형태로 제공 받는다.
- toString()
- 예외 메시지를 String 형태로 제공 받는다.
getMessage()보다 더 자세하게 예외 클래스 이름도 같이 제공한다.
- printStackTrace()
- 가장 첫 줄에는 예외 메시지를 출력하고, 두 번째 줄부터는 예외가 발생하게 된 메소드들의 호출 관계(스택 트레이스)를 출력해준다.
- 많은 양의 로그가 쌓이기 떄문에 개발할 때만 사용하는 것을 권고
-
throws
-
예외 발생시키는 방법
-
try블록 내에 throw라고 명시한 후 개발자가 예외 클래스의 객체를 생성 하거나 생성되어있는 객체 명시한다. 그러면 throw한 문장 이후에 있는 try블록 내의 문장들은 수행 되지 않고, catch블록으로 이동한다.
-
catch블록 중에 throw한 예외와 동일하거나 상속 관계에 있는 예외가 있다면 그 블록에서 예외를 처리할 수 있다.
-
throws
- 발생한 예외의 catch문이 없다면 발생된 예외는 메소드 밖, 즉 예외가 발생된 메소드를 호출한 메소드로 던진다.
- 이렇게 선언하면, 예외가 발생했을 때 try-catch로 묶어주지 않아도 그 메소드를 호출한 메소드로 예외 처리를 위임한다.
- throws 뒤에 선언한 예외가 발생하면 호출한 메소드로 예외가 전달된다.
- 여러 개일 때 콤마로 구분
- catch블록에서 예외를 throw할 경우에도 메소드 선언의 throws 구문에 해당 예외가 정의되어 있어야 한다.
- throws 문장으로 컴파일 오류가 생겼을 경우 해결 방법
- 호출한 메소드를 try-catch로 묶는다.
- 호출한 메소드에서도 다시 throws 한다. (권장x)
public void throwsException(int number) throws Exception {
if(number>12)
throw new Exception("Number is over than 12");
System.out.println("Number is " + number);
}
- 임의의 예외 클래스를 만들 때는 Throwable이나 그 자식 클래스의 상속을 받아야한다.
- 자바에서 예외를 처리할 떄에는 표준을 정해 두어야 한다.
catch문 내에서 어떻게 처리할지를 명시적으로 선언해 두어야 한다.
- catch문에서 로그에 남기는 등의 작업을 하고
예외를 throw를 이용해 던져 주어야 문제가 발생한 정확한 원인을 찾을 수 있다.
- 임의의 예외 클래스를 만들 때에는, 반드시 try-catch로 묶어줄 필요가 있을 경우에만 Exception 클래스를 확장한다. 일반적으로 실행시 예외를 처리할 수 있는 경우에는 RuntimeException 클래스를 확장하는 것을 권장한다.