예외처리?
프로그램의 실행중 발생하는 에러는 어쩔 수 없지만, 예외는 프로그래머가 이에 대한 처리를 미리 해주어야 한다.
예외처리(exception handling)는 프로그램 실행 중 발생할 예외에 대비한 코드를 작성하여
예외의 발생으로 인한 프로그램의 갑작스런 비정상 종료를 막고, 정상적인 실행상태를 유지 하는 것이다.
예외처리(exception handling)의
정의 - 프로그램 실행 시 발생할 수 있는 예외에 대비한 코드를 작성하는 것
목적 - 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지 하는것
발생한 예외를 처리하지 못하면 프로그램은 비정상 종료되고,
처리되지 못한 예외(uncaught exception)는 JVM의 '예외처리기(UncaughtExceptionHandler)'가
예외의 원인을 화면에 출력해준다.
try-catch
예외를 처리하기 위해서는 try-catch문을 사용한다.
try {
// 예외가 발생할 가능성이 있는 문장
} catch (IOException e) {
// IOException 이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch (RuntimeException e) {
// RuntimeException 이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch (ArithmeticException e) {
// ArithmeticException 이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
}
try 다음에는 여러 종류의 예외를 처리할 수 있도록
하나 이상의 catch블록이 올 수 있고, 이 중 발생한 예외의 종류와 일치하는
단 한개의 catch블록만 수행된다.
예외가 발생하면, 발생한 예외에 해당하는 클래스의 인스턴스가 만들어지고
이 예외를 처리할 수 있는 catch 블록이 있는지 찾게 되고
발생한 예외의 종류와 일치하는 catch블록이 없으면 예외는 처리되지 않는다.
public static void main(String[] args) {
try {
System.out.println(0/0);// ArithmeticException을 발생시킨다.
}catch(Exception e) {
System.out.println(5);
}
}
위의 코드는 ArithmeticException를 발생시켰지만 catch의 ()에 Exception타입의
참조변수를 선언하였다.
ArithmeticException클래스는 Exception클래스의 자손이므로
ArithmeticException instanceof Exception가 ture가 되어
Exception클래스 타입의 참조변수를 선언한 catch블럭의 문장이 수행되면서
예외가 처리 된다.
public static void main(String[] args) {
try {
System.out.println(0/0);// ArithmeticException을 발생시킨다.
} catch(ArithmeticException ea) { // ArithmeticException을 처리한다.
System.out.println("ArithmeticException");
} catch(Exception e) {
// ArithmeticException이 이미 처리되었기 때문에 처리된 Excpetion을 제외한 모든 Exception이 처리된다.
System.out.println("Exception");
}
}
위의 코드는 try블록에서 ArithmeticException이 발생하였으므로 catch블록을 하나씩 차례로 검사하게 된다.
첫번째 검사에서 catch블록을 찾았기 때문에 그 뒤에오는 catch블록들은 생략하게 된다.
ArithmeticException이 아닌 다른 종류의 예외가 발생하면 두 번째 catch블록인 Exception클래스 타입의
참조변수를 선언한 곳에서 처리되었을 것이다.
try {
...
}catch (IOException | RuntimeException e) {
...
}
catch블럭을 '|' 기호를 이용해 하나의 catch블럭으로 합칠 수 있고 이를 '멀티 catch블럭'이라 한다.
'멀티 catch'을 이용하면 중복된 코드를 줄일 수 있다. 그리고 '|'기호로 연결할 수 있는 예외 클래스의
개수에는 제한이 없다.
finally 블럭
finally블럭은 예외의 발생여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용된다.
try-catch문의 끝에 선택적으로 덧붙여 사용할 수 있으며, try-catch-finally의 순서로 구성된다.
예외가 발생한 경우 'try → catch → finally'의 순서로 실행되고
예외가 발생하지 않는 경우 'try → finally'의 순서로 실행된다.
try {
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch(Exception e) {
// 예외처리를 위한 문장을 적는다.
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 넣는다.
// finally블럭은 try-catch문의 맨 마지막에 위치한다.
}
예외 발생시키기
키워드 throw를 사용해서 고의로 예외를 발생시킬 수 있고 방법은 다음과 같다.
1. 먼저, 연산자 new를 이용해 발생시키려는 예외 클래스의 객체를 만든 다음
Exception e = new Exception("고의로 발생시켰음");
2. 키워드 throw를 이용해서 예외를 발생시킨다.
throw e;
try{
Exception e = new Exception(); // 연산자 new를 이용해 클래스의 객체 생성
throw e // 키워드 throw를 이용해서 예외 발생
}catch(Exception e) {
...
}
printStackTrace()와 getMessage()
예외가 발생하여 생성된 예외 클래스의 인스턴스는 예외에 대한 정보를 가지고 있다
이 정보들은 getMessage()와 printStackTrace() 메서드를 통해 얻을 수 있다.
printStackTrace() : 예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와
예외 메시지를 화면에 출력한다.
getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
try {
Exception e = new Exception(); // Exception 인스턴스 생성
throw e // throw를 이용해서 예외를 발생시킴
} catch(Exception e) {
e.printStackTrace();
System.out.println(ae.getMessage());
}
메서드에 예외 선언하기
try-catch문을 사용하는 것 외에, 예외를 메서드에 선언하는 방법이 있다.
메서드 선언부에 키워드 throws를 사용해서 메서드에서 발생할 수있는 예외를
적어주기만 하면 된다. 예외가 여러 개일 경우 쉼표(,)로 구분한다.
void method() throws Exception1, Exception2, Exception3, ... ExceptionN {
// 메서드의 내용
}
메서드의 선언부에 예외를 선언함으로써 메서드를 사용하려는 사람이
이 메서드를 사용하기 위해서는 어떤 예외들이 처리되어져야 하는지
쉽게 알수있다.
throws를 사용하여 예외 처리를 할 경우
이 메서드를 사용하여 만들어지는 메서드에 try-catch를 해서 처리 해주어야한다.
댓글