예외처리(Exception)
소프트웨어를 사용하다보면 여러가지 오류상황이 발생하게 된다. 아무리 잘 만든 소프트웨어라고 하더라도 예외는 얼마든지 발생할 수 있다. 이런 상황이 생기더라도 갑자기 종료되는 상황이 일어나지 않도록 예외처리를 하는 것이 중요한데, 예외 처리 방법에 대해 알아보자!
예외 클래스
오류란?
프로그램에서 오류가 발생하는 상황은 두 가지가 있다.
1. 컴파일 오류 - 코드 작성중 실수로 발생함
2. 실행오류 - 실행중인 프로그램이 의도하지 않은 동작을 하거나 중지되는 오류(런타임 에러)
실행 오류 중 프로그램을 잘못 구현하여 의도한 바와 다르게 실행되어 발생하는 오류를 버그라고 한다. 컴파일 오류같은 경우 개발환경에서 대부분 원인을 알 수 있다. 그러나 프로그램 실행중 발생하는 오류는 예측하기 어렵고 비정상적으로 종료되면서 멈춰버린다. 실제로 제공되고 있는 프로그램의 경우 오류가 생기면 서비스가 중단되기에 문제가 매우 심각해진다.
또, 실행중 오류가 생긴다면 그 상황을 재현하여 테스트해야하는데 실제 시스템이나 서비스가 운영중인 경우에는 쉽지 않다. 따라서 로그 분석을 통해 원인을 찾을 수 있도록 프로그램 개발시 로그를 정확히 남기는 것이 중요하다.
로그란?
로그는 소프트웨어 실행중에 발생하는 여러 상황을 기록한 내용. 주로 파일에 기록함. 이 파일을 로그 파일 이라고 한다.
자바는 비정상적인 종료를 줄이기 위해 다양한 예외처리 방법을 가지고 있다, 목적은 프로그램의 비정상적인 종료를 방지하기 위함이다. 그리고 예외 발생시 로그를 남기면 예외를 파악하고 버그를 수정하는데 도움을 받을 수 있다.
실행오류의 두 가지, 오류/ 예외
실행 오류에는 크게 두 가지가 있다.
1. 시스템 오류 - 자바 가상 머신에서 발생함, 이러한 시스템 오류는 프로그램에서 제어가 불가능하다.
2. 예외 - 예외는 프로그램에서 제어할 수 있다. ex) 파일을 읽어 사용하려는데 파일이 없는 경우, 네트워크로 데이터를 전송하려고 하는데 연결이 안 된 경우, 배열 값을 출력하려 하는데 배열 요소가 없는 경우 등등
오류 클래스는 모드 Throwable 클래스에서 상속받는다. Error 클래스의 하위 클래스는 시스템에서 발생하는 오류를 다루며 프로그램에서 제어하지 않는다. 프로그램에서 제어하는 클래스는 Exception 클래스와 그 하위에 있는 클래스들이다.
예외 클래스의 종류
exception 하위 클래스에는 매우 많은 클래스들이 존재한다. 이것은 구글링을 통해 찾아보자( 너무 방대함)
예외를 처리하는 방법
try-catch 문 - 예외를 처리하는 가장 기본적인 문법
try {
//예외가 발생할 수 있는 코드 부분
} catch(처리할 예외 타입 e) {
//try 블록 안에서 예외가 발생했을 때 예외를 처리하는 부분
}
위 코드는 트라이 캐치 문의 가장 기본적인 형식이다. 트라이 블록에는 예외 발생 가능성이 있는 코드를 작성한다.
만약에 트라이 블록 안에서 예외가 발생하면, catch 블록이 수행된다.
EX)
@Test
void arithmeticException() {
String[] strings = new String[]{"hello", "crong", "coco"};
for (int i = 0; i < 4; i++) {
System.out.println(strings[i]);
}
}
위 코드는 반복문 for문을 통해 순차적으로 배열의 값을 출력하는 코드이다. 하지만, 이 코드는 코드 수행시 에러가 발생한다.
이 에러가 발생하는 이유역시 결과창에 출력된다. 길이가 3인 배열의 index 3을 찾으려 하기에 에러가 발생했다는데, 예외 클래스명과 연관지어서 생각하면, 배열의 길이를 벗어난 인덱스의 값을 가져오려 했기에 생긴 문제라는 것이다.
이 코드를 try-catch 문을 사용해 에러가 발생하지 않게 만들어보았다.
@Test
void arithmeticException() {
//before
String[] strings = new String[]{"hello", "crong", "coco"};
try {
for (int i = 0; i < 4; i++) {
System.out.println(strings[i]);
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Empty");
}
}
컴파일러에 의해 예외가 체크되는 경우
자바에서 제공하는 많은 예외 클래스들은 컴파일러에 의해 처리된다. 이런 경우 자바에서는 예외처리를 하지 않으면 컴파일 오류가 계속난다. 파일 입출력에서 발생하는 예외를 처리하는 과정을 예로 들 수 있다.
예외처리를 한다고 해서 프로그램의 예외 상황 자체를 막을 수 있는 것은 아니다. 하지만 예외처리를 하면 예외 상황을 알려주는 메세지를 볼 수 있고, 프로그램이 비정상적으로 종료되지 않고 계속 수행되도록 만들 수 있다.
try-catch문에서의 흐름
흐름
예외 발생시키기
try- with-resource 문
트라이 블록 내에서 열린 리소스를 클로스 메서드를 명시적으로 호출하지 않아도 자동으로 닫도록 만들 수 있다. 이 문법을 사용하려면 AutoCloseable 인터페이스를 구현해야한다. 자세한건 JavaDoc에서 찾아보자.
예외처리 미루기
예외 처리를 미루는 throws 사용하기
Add throws declaration throws 선언을 추가하여 예외를 해당 메서드에서 처리하지 않고 미룬 후 메서드를 호출하여 사용하는 부분에서 예외를 처리한다.
예외를 처리하지 않고 미룬다고 선언하면, 그 메서드를 호출하여 사용하는 부분에서 예외처리를 해야한다.
예외가 발생한 메서드에서 그 예외를 바로 처리할 것인지, 아니면 미루어서 그 메서드를 호출하여 사용하는 부분에서 처리할 것인지는 프로그램에 따라 다를 수 있다. 만약 어떤 메서드가 다른 코드에서 호출되어 사용된다면 호출하는 코드의 상황에 맞게 로그를 남기거나 예외처리를 하는 것이 좋다. 이런 경우에는 메서드를 호출하는 부분에서 예외처리를 하도록 미루는 것이 합리적이다.
사용자가 직접 정의하여 예외 클래스를 구현할 수도 있는데 글이 너무 길어질 것 같으니 다음 글에서 확인하도록하자!
'공부 STUDY > JAVA' 카테고리의 다른 글
[JAVA] 자바 입출력과 스트림 - (1) | scanner 클래스와 Console 클래스에대해 알아보자 (0) | 2023.01.23 |
---|---|
[JAVA] 사용자 정의 예외 클래스 구현하기 | 아이디 설정 조건에서 예외 발생에대한 클래스를 구현해보자! | 사용자 정의 예외 (0) | 2023.01.23 |
[JAVA] 람다식이란? 람다식 사용 방법에대해 알아보자! (1) | 2023.01.23 |
[JAVA] 스트림(Stream)이란 무엇일까? (0) | 2023.01.23 |
[JAVA] 내부 클래스(inner class)와 익명 클래스(anonymous class)에대해 알아보자 (1) | 2023.01.21 |