- 에러 (error) : 프로그램 코드에 의해 수습될 수 없는 심각한 오류 (OutOfMemoryError , StackOverflowError)
- 예외 (exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
모든 클래스의 조상은 Object 클래스이므로 Exception과 Error 클래스 역시 Object 클래스의 자손들이다.
Exception
iOException
ClassNotFoundException
...
RuntineExceptionArithmeticException
ClassCastException
NullPointerException
...
IndexOutOfBoundsException
✅ Exception 클래스와 그 자손들이 발생할 가능성이 있는 문장들에 대해 예외처리를 반드시 해주어야 한다. (예외처리를 해주지 않으면 컴파일되지 않는다. )
✅ RuntimeException 클래스와 그 자손들에 해당하는 예외는 프로그래머가 실수로 발생하는 것이기 때문에 예외처리를 강제하지 않는다.
➡️ 따라서 기존에는 Exception을 상속받아 checked 예외로 작성하는 경우가 많았지만, 최근에는 예외처리를 선택적으로 할 수 있도록 RuntimeException을 상속받아서 작성하는 경향이 있다.
프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것
에러는 어쩔 수 없지만, 예외에 대한 처리는 프로그래머가 미리 해주어야 한다!
try-catch
문 이용
try{
// 예외가 발생할 가능성이 있는 코드를 넣는다.
} catch (Exception1 e1){
} //Exception2가 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch (Exception2 e2){
} //Exception2가 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
try {
} catch (Exception1 e1){ }
catch 블럭의 괄호( ) 내에는 처리하고자 하는 예외(Exception1)와 같은 타입의 참조변수 하나(e1)를 선언해야 한다.
예외가 발생하면 해당 예외 클래스의 인스턴스가 만들어진다.
선언된 참조변수의 종류와 생성된 인스턴스가 동일한지를 instanceOf
연산자를 사용해 검사한다.
(instanceOf
는 객체가 어떤 클래스인지, 어떤 클래스를 상속받았는지 확인하는데 사용하는 연산자)
모든 예외 클래스는 Exception 클래스의 자손이므로, catch 블럭의 괄호에 Exception 타입의 참조변수를 선언해 놓으면 어떤 종류의 예외가 발생하더라도 이 catch 블럭에 의해 처리된다.
-> 예외 발생 원인을 확인할 수 있는 메서드
throw
를 사용해서 고의로 예외를 발생시킬 수 있다.
new
를 사용해서 발생시키려는 예외 클래스의 객체 만들기 Exception e = new Exception("고의로 발생시킨 예외");
throw e;
위 두 코드를 합칠 수도 있다.
throw new Exception("고의로 발생시킨 예외");
try{
// 예외가 발생할 가능성이 있는 코드를 넣는다.
} catch (Exception1 e1){
// 예외처리를 위한 문장을 적는다.
} finally{
// 예외의 발생여부에 관계 없이 항상 수행되어야하는 문장들을 적는다.
// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}
class MyException extends Exception{
MyException(String msg){ //문자열을 매개변수로 받는 생성자
super(msg); //조상인 Exception클래스의 생성자를 호출한다.
}
}
Exception 클래스로부터 상속받아서 MyExceptioin클래스를 만들었다. (필요하다면 멤버변수나 메서드를 추가할 수 있다.)
Exception 클래스는 생성 시에 String값을 받아서 메시지로 저장할 수 있다.
사용자정의 예외 클래스도 메시지를 저장할 수 있으려면, 위의 코드와 같이 String을 매게변수로 받는 생성자를 추가해주어야 한다.
super()
내용은 🔗super! 를 참고하자
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(기본값)으로 초기화한다.
}
public int getErrCode() { // 에러 코드를 얻을 수 있는 메서드도 추가한다.
return ERR_CODE;
}
}
메시지뿐만 아니라 에러코드 값도 저장할 수 있게 한다.
class Ex8_12{
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
System.out.println("main 메서드에서 예외가 처리되었습니다.");
}
} // 메인 메서드의 끝
static void method1() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e;
}
}
}
예외가 발생할 가능성이 있는 메서드에서 try-catch
문을 사용해서 예외를 처리해주고,
catch문에서 필요한 작업을 진행한 후에 throw
문을 사용해서 예외를 다시 발생시킨다.
다시 발생한 예외는 이 메서드를 호출한 메서드에게 전달되고 호출한 메서드의 try-catch문에서 예외를 또다시 처리한다.