[Java] Try-catch 문이란? (예외처리)
1) 예외 처리하기
Try-catch문은 예외를 처리하기 위한 구문이다.
Error(에러)와 Exception(예외의 차이)
에러란 컴퓨터 하드웨어의 오작동 또는 고장으로 인해 응용프로그램에 이상이 생겼거나 JVM 실행에 문제가 생겼을 경우 발생하는 것을 말한다. 이 경우 개발자는 대처할 방법이 극히 제한적이다. 하지만 예외는 다르다. 예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다. 예외가 발생하면 프로그램이 종료가 된다는 것은 에러와 동일하지만 예외는 예외처리를 통해 프로그램이 종료되지 않고 정상적으로 작동되게 만들어 줄 수 있다. 자바에서 예외 처리는 Try-catch 문을 통해 만들 수 있다.
try-catch
try {
//예외발생할 가능성이 있는 문장
}catch(Exception1 e1) {
//Exception1이 발생했을 경우, 이를 처리하지 위한 문장적는다.
//보통 이곳에 예외메세지를 출력하고 로그로 남김.
}catch(Exception2 e2) {
//Exception2이 발생했을 경우, 이를 처리하지 위한 문장적는다.
}catch(ExceptionN eN) {
//ExceptionN이 발생했을 경우, 이를 처리하지 위한 문장적는다.
}finally{
//예외발생여부에 관계없이 상항 수행되어야 하는 문장적는다.
}
try 문에서 Exception 예외가 발생할 경우 catch(Exception e)로 빠져서 그 안의 실행문을 실행한다.
마지막의 finally 블록은 try-catch문과 함께 예외 발생 여부와 관계없이 "항상. 무조건" 실행되어야 할 코드를 적는다.
필수는 아니며 마지막에 선택적으로 덧붙여 사용한다.
예외 발생 시 try -> catch -> finally 순으로, 발생하지 않은 경우 try -> finally 순으로 실행된다.
보통 finally 블록은 자원이나 DB에 커넥션 한 경우, 파일 닫기, 연결 닫기(close) 등과 같은 "정리" 코드를 넣는 데 사용된다.
try-catch문
-예외가 try 블록에서 발생한 경우
- 발생한 예외와 일치하는 catch 문이 있는지 확인.
- 일치하는 catch 문이 있다면 catch 블록 내의 문장을 모두 실행하고 try catch 문을 빠져나간 후 그 다음 문장을 수행.
- 일치하는 catch 문이 없다면 예외는 처리되지 못하고 에러 발생.
-예외가 try 블럭 안에서 발생하지 않는 경우
- catch 블록을 거치지 않고 전체 try-catch 문을 빠져나가서 수행을 계속.
-예외가 try 블럭 밖에서 발생한 경우
- 예외는 아무 처리되지 못 한 채 에러 발생.
Try-catch 블록에서 예외 발생시, 예외가 발생한 위치 이후에 있는 try 블럭의 문장들은 수행되지 않으므로, try블럭에 포함시킬 코드의 범위를 잘 선택해야 한다.
Catch 블럭
괄호()와 블록{} 두 부분으로 나눠져 있는데, 괄호에는 처리하고자 하는 예외 타입(Exception), 참조 변수(e)를 선언한다.
예외 발생 시 발생 예외에 해당하는 클래스의 인스턴스가 만들어진다.
예를 들어 AuthException이 발생한다고 하면 AuthException인스턴스가 생성된다.
try블록 내에서 이 예외가 발생했다면, 이를 처리할 수 있는 catch 블록이 있는지 찾는다.
catch (AuthException e) {
e.printStackTrace(); //예외정보 출력
log.error("AuthException ERROR: {} ", e.getMassage()); //로그남김
throw e; //예외 던지기
} catch (Exception e ) {
e.printStackTrace();
log.error("Exception ERROR: {} ", e.getMassage());
throw e;
}
이때, AuthException을 처리하는 catch 블록이 없다면, 예외가 처리되지 못하고 에러를 발생시키기 때문에 모든 예외 클래스는 Exception 클래스의 자손이므로, catch블록 괄호에 Exception e를 선언해 놓으면 어떤 종류의 예외가 발생하더라도 이 catch블록에 의해 처리된다. 마치 if-else 문의 else 부분이라고 볼 수 있다.
그래서 보통 마지막 catch 블럭에 Exception e를 선언한다.
예시 같은 경우에는 두 번째 catch블록에서 AuthException을 제외한 모든 예외가 처리되는 것이다.
printStackTrace()
:예외 발생 당시의 호출 스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 콘솔 화면에 출력한다. getMessage 와는 다르게 printStackTrace는 리턴 값이 없다. 이 메서드를 호출하면 메서드가 내부적으로 예외 결과를 화면에 출력한다.
printStackTrace는 가장 자세한 예외 정보를 제공한다.
java.lang.AuthException:
at org.opentutorials.javatutorials.exception.Calculator.divide(CalculatorDemo.java:11)
at org.opentutorials.javatutorials.exception.CalculatorDemo.main(CalculatorDemo.java:25)
.
.
getMessage()
: 발생한 예외 클래스의 인스턴스에 저장된 메시지를 얻을 수 있음.
오류에 대한 기본적인 내용을 알 수 있지만 상세하지 않음.
2) 예외 던지기(Throw)
throw e
:예외 던지기(예외 발생시키기)
throw 키워드를 사용하여 프로그래머가 고의로 예외를 발생시킬 수 있다.
최상단 클래스를 제외한 나머지 클래스에서의 예외처리는 반드시 Throw를 해줘야 한다. 그렇지 않으면 예외처리를 했음에도 불구하고 Main에서는 Exception을 전달받지 못하여 개발자가 예외를 인지 못하는 경우가 생긴다.
예외 던지기
- try안에서 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체 생성.
- 키워드 throw를 사용해서 생성한 예외를 catch로 던진다.
- catch에서 던진 예외를 잡아서 확인 또는 처리한다.
public static void main (String[] args) {
try {
Exception e = new Exception("고의발생"); // 1. 예외 생성
throw e; // 2. 예외 던지기
} catch (Exception e) {
System.out.println("에러메세지:" + e.getMessage());
e.printStackTrace(); //예외정보 출력
}
System.out.println("프로그램 정상 종료.");
}
에러메세지: 고의발생
java.lang.Exception: 고의발생
at ExceptionEx9.main(ExceptionEx9.java:4)
프로그램 정상 종료.