December 23, 2021
이중 런타임에러를 방지하기 위해 프로그램의 실행 중 발생할 수 있는 모든 경우의 수를 고려하여 이에 대한 대비가 필요하다 자바에서는 런타임에러에서 발생할 수 있는 프로그램 오류를 에러와 예외로 구분한다.
위의 사진처럼 모든 예외의 최고 조상 클래스는 Exception 클래스이다.
또한 Exception의 자손클래스들은 위에 사진처럼 2가지 그룹으로 나눌 수 있다.
Exception 클래스와 그 자손들
RuntimeException 클래스와 그 자손들
예외처리(exception handling)란, 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것이다.
try{
// 예외가 발생할 가능성이 있는 문장들이 들어감
}catch(Exception1 e1){
// Exception1 이 발생할 경우 이를 처리할 문장이 들어감
}catch(Exception2 e2){
// Exception2 이 발생할 경우 이를 처리할 문장이 들어감
}catch(Exception3 e3){
// Exception3 이 발생할 경우 이를 처리할 문장이 들어감
}
위의 예시처럼 하나의 try블럭에는 여러종류의 예외를 처리할 수 있도록 하나 이상의 catch 블럭이 올 수 있다.
발생한 예외의 종류와 일치하는 단 한개의 catch 블럭만 수행된다. 마치 else if 문과 비슷하다.
이때 발생한 예외와 일치하는 catch블럭을 찾을 때는 예외 클래스의 인스턴스에 instanceof 연산자를 사용하여 일치하는 예외클래스를 찾는다.
모든 예외 클래스는 Exception의 자손이므로, catch 블럭의 괄호()에 Exception 클래스 탑이의 참조 변수를 선언해 놓으면 어떤 종류의 예외가 발생하더라도 이 catch블럭에 의해서 처리된다.
예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메세지를 화면에 출력한다.
발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
throw 명령어를 통해 예외를 발생시킬 수 있으며, Exception 인스턴스를 생성할 때 생성자에 String을 넣어주면 Exception 인스턴스에 메시지로 저장되며 이를 getMessage()를 통해 얻을 수 있다.
연산자 new를 이용하여 발생시키려는 예외 클래스의 객체를 만든다
throw 키워드를 사용하여 예외를 발생시킨다.
메서드에 throws 키워드를 사용하여, 메서드 내에서 발생하는 예외에 대해 적어 줄 수 있다.
void method() throws Exception1, Exception2, ... ExceptionN{
/// 메서드 내용
}
finally 블럭은 예외의 발생 여부에 상관없이 실행되어야 할 코드를 포함시킬 목적으로 사용된다. try - catch - finally
try{
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
}catch(Exception1 e1){
// 예외처리를 위한 문장을 적는다.
}finally{
// 예외의 발생여부와 관계없이 항상 수행되어야 하는 문장들을 넣는다
// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}
try에 사용한 후에 꼭 닫아줘야하는 자원 객체를 전달하면, try 코드 블럭이 끝나면 자동으로 자원을 종료해주는 기능이다.
try(SomeResource resource = getResource()){
use(resource);
} catch(...){
...
}
위와 같이 try문의 괄호()안에 객체를 생성하는 문장을 넣으면, 이 객체는 따로 close()를 호출하지 않아도 try블럭을 벗어나는 순간 자동적으로 close()가 호출된다.
이후 catch 블럭 또는 finally 블럭이 수행된다.
기존의 정의된 예의 클래스 외에 필요에 따라 새로운 예외 클래스를 만들어야한다. 보통 Exception 클래스 또는 RuntimeException 클래스로부터 상속받아 클래스를 만든다.
class MyException extends Exception{
MyException(String msg){ // 문자열을 매개변수로 받는 생성자
super(msg); // 조상인 Exception 클래스의 생성자를 호출해야한다.
}
}
따라서 다음과 같은 예제처럼 기존 Exception 클래스를 향상시킬 수 있다.
class MyException extends Exception{
//에러 코드 값을 저장하기 위한 필드를 추가
private final int ERR_CODE; // 생성자를 통해 초기화 한다
MyException(String msg, int errCode){ // 생성자
super(msg);
ERR_CODE = errCode;
}
MyException(String msg){
this(msg, 100) // ERR_CODE를 100(defualt)로 초기화 한다
}
public int getErrCode(){
return ERR_CODE; //get Message 처럼 사용될 예정.
}
}