[Java] 예외처리
자바에서 예외 처리 방법 ( try, catch , throw , throws ,finally)
1) 예외처리란?
코드 작성 중 예기치 않게 발생하는 에러들에 대응할 수 있도록 사전에 방지하는 것이다.
어떤 경우에 의해 실행 시 발생하는 프로그램 중단을 강제 종료하지 않도록 처리한다.
2) try ~ catch
예외를 직접 처리하는 구문
[형식]
try {
예외가 발생될 코드
} catch(Exception e) { }
ex)
public class Main {
public static void main(String[] args) {
int a = 5;
int b = 0;
try {
System.out.println(a/b);
}catch(ArithmeticException e){
System.out.println(e.getMessage());
}
}
}
3) throw
예외 클래스를 명시 실행
일부로 에러를 내서 로그에 기록하고 싶을 경우 throw 하여 에러를 catch 함
[형식]
throw new [Exception] (" 메세지 ");
ex)
public class Main {
public static void main(String[] args) {
int a = 5;
int b = 0;
try {
if(b <=0 ){
throw new ArithmeticException("음수나 0으로 나눌 수 없습니다.");
}
System.out.println(a/b);
}catch(ArithmeticException e){
System.out.println(e.getMessage());
System.exit(1);
}
}
}
4) throws
예외를 다른 곳에서 처리하도록 떠넘김
throw 는 메소드 선언부 끝에 작성되어 메소드에서 예외를 직접 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 함
[형식]
void method() throws [Exception] {....}
ex)
public class Main {
public static void main(String[] args) throws ArithmeticException{
int a = 5;
int b = 0;
try {
throwsEx(a,b);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
public static void throwsEx(int a, int b){
System.out.println("throw a/b: "+a/b);
}
}
5) finally
예외 발생 유무와 관계 없이 실행됨 -> 무조건 실행되는 코드를 작성
[형식]
try{ .....}
catch([Exception]) {...}
finally{ ....}
ex)
public class Main {
public static void main(String[] args) throws ArithmeticException{
int a = 5;
int b = 0;
try {
throwsEx(a,b);
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
System.out.println("프로그램을 종료합니다.");
}
}
public static void throwsEx(int a, int b){
System.out.println("throw a/b: "+a/b);
}
}
자바가 제공하는 예외 계층 구조
Unchecked Exception : 명시적인 처리를 강제하지 않음 , 실행 시점 -> RuntimeException 은 예외처리를 강제하지 않음
Checked Exception : 강제로 예외처리를 하도록 강요 , 컴파일 시점
Exception 과 Error 의 차이는?
1) Exception이란?
Exception은 예외로 개발자가 만든 코드 내에서 오작동이 난 것이고 경우의 수를 생각하여 미리 대비할 수 있는 방법들이 있다.
2) Error 이란?
Error 는 에러로 ThreadDeath 쓰레드가 죽어버리거나 VirtualMachineError JVM 이 작동을 안하는 것과 같이 개발자가 만든 코드 내에서 오작동이 난 것이 아닌 그 밖의 영역에 문제다.
3) 둘의 차이점
위에서 말했듯이 Exception은 코드 내 오작동으로 일어난 것으로 미리 대비할 수 있는 방법이 많지만 Error는 코드 내에서 오작동 난 것이 아닌 그 밖의 영역으로 미리 대비할 수 있는 방법이 별로 없다는 것이다.
RuntimeException 과 RE가 아닌 것의 차이는?
위 그림에서 봤듯이 Exception은 Unchecked Exception과 Checked Exeption으로 나뉘는 것을 볼 수 있다.
RuntimeException은 Unchecked Exception으로 컴파일 단계가 아닌 실행 단계에서 검사하는 예외이다.
이는 Error도 포함하는데 에러 역시 컴파일 단계에서 알 수 없다. 즉 실행 중간에 발생하는 문제점들로 이 시점에 문제들을 처리하는 객체이다.
Checked Exception은 컴파일 단계에서 비정상적인 상황을 처리하는 방식이다. 따라서 반드시 명시적으로 이 문제를 처리하는 코드를 추가해야한다. 그렇지 않을 경우 컴파일 에러가 발생한다.
커스텀한 예외 만드는 방법
1) 일반 예외와 실행예외 중 어떤 것을 상속 받아 구현할 지 결정
일반 예외로 선언할 경우 -> Exception 상속 받아 구현 (Checked Exception)
실행 예외로 선언할 경우 -> RuntimeException 상속 받아 구현 ( Unchecked Exception)
2) 사용자 이름 설정하기
뒤에 Exception으로 끝나는 것을 권장
3) 사용자 정의 예외 클래스 작성 시 생성자 선언
사용자 정의 예외 클래스 작성 시 생성자는 두 개를 선언하는 것이 일반적
- 매개 변수가 없는 기본 생성자
- 예외 발생 원인( 예외 메세지)를 전달하기 위해 String 타입의 매개변수를 갖는 생성자
여기서 예외 처리 메세지 용도는 catch{} 블록의 예외처리 코드에서 이용하기 위함임
class CustomException extends RuntimeException {
CustomException() { }
CustomException(String message ) {super(message);}
}
public class Main {
public static void main(String[] args) {
try{
test();
}catch(CustomException e){
System.out.println("커스텀 예외 테스트");
}
}
public static void test() throws CustomException {
throw new CustomException("예외 테스트입니다.");
}
}