Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 예외 처리 완벽 가이드: try-catch와 finally 문 활용법

아무리 뛰어난 프로그래머라도 코드에서 실수를 하기 마련입니다. 오타 하나, 예상치 못한 사용자 입력, 혹은 추적하기 어려운 다양한 원인으로 인해 오류는 언제든 발생할 수 있습니다.

바로 이럴 때 예외 처리(Exception Handling)가 필요합니다. 잘 작성된 코드에는 예외 핸들러가 포함되어 있어, 오류가 발생했을 때 미리 정의된 방식으로 대응할 수 있습니다. 예외 핸들러는 프로그램에 오류 발생 시 어떻게 반응해야 하는지 지시하는 역할을 하기 때문에 매우 유용합니다.

Java에서는 try...catch 블록을 사용해 예외를 처리합니다. 이 글에서는 예외 처리의 기본 개념부터 try...catch 블록을 활용한 예외 처리 방법, 그리고 finally 문과 함께 사용하는 방법까지 실제 예제와 함께 자세히 살펴보겠습니다.

Java 예외(Exception)란 무엇인가?

예외(Exception)란 프로그램이 실행되는 도중에 발생하는 예기치 못한 사건을 의미합니다. 예외가 발생하면 프로그램의 정상적인 흐름이 중단되며, 심한 경우 프로그램이 완료되기 전에 종료될 수도 있습니다.

예외는 다양한 이유로 발생합니다. 대표적인 원인은 다음과 같습니다.

  • 서버에 접근할 수 없는 경우
  • 코드 자체의 논리적 오류
  • 오타로 인한 실수
  • 존재하지 않는 파일을 열려고 시도하는 경우
  • 잘못된 사용자 입력

여기서 주의할 점은 Java에서 오류(Error)예외(Exception)는 서로 다른 개념이라는 것입니다. 오류는 메모리 부족처럼 프로그램이 복구할 수 없는 심각한 상황을 의미하며, 일반적으로 개발자가 직접 처리하지 않습니다.

반면 예외는 프로그램 내에서 처리 가능한 문제입니다. 예외가 발생하면 예외 객체(exception object)가 생성되는데, 이 객체에는 예외의 이름과 발생 위치 같은 정보가 담겨 있습니다.

Java 예외 처리의 기본 개념을 이해했다면, 이제 try...catch 문을 사용해 예외를 직접 처리하는 방법을 알아보겠습니다.

try-catch 기본 구조

try...catch 문은 Java에서 예외를 처리하는 핵심 구문입니다. 예외를 처리하려면 해당 코드 블록을 try...catch 블록 안에 배치하면 됩니다.

프로그램이 try...catch 블록을 만나면 먼저 try 블록 안의 코드가 실행됩니다. 실행 중 예외가 발생하면 즉시 catch 블록의 코드가 실행됩니다. 단, catch 블록은 반드시 try 블록 뒤에 위치해야 합니다.

Java에서 try...catch 문의 기본 문법은 다음과 같습니다.

try {
    // 실행할 코드
} catch (ExceptionType error) {
    // 예외가 발생했을 때 실행할 코드
} finally {
    // 예외 발생 여부와 관계없이 실행할 코드
}

finally 블록에 대해서는 뒤에서 자세히 다루고, 우선 try...catch 블록의 동작 방식을 예제를 통해 확인해 보겠습니다.

try-catch 실전 예제

studentNames라는 배열을 사용하는 프로그램을 만든다고 가정해 보겠습니다. 학생 명단에서 다섯 번째(인덱스 5) 이름을 콘솔에 출력하고 싶은데, 클래스에는 학생이 5명뿐입니다.

존재하지 않는 값을 참조하려고 하기 때문에 코드에서 오류가 발생합니다. 인덱스 값은 0부터 시작하므로, 인덱스 5는 여섯 번째 학생을 의미합니다. 다음 예제를 살펴보겠습니다.

class Main {
public static void main(String[] args) {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
}

이 코드를 실행하면 다음과 같은 결과가 출력됩니다.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at Main.main(Main.java:4)

프로그램이 존재하지 않는 값을 참조하려 했기 때문에 긴 오류 메시지가 반환된 것을 볼 수 있습니다.

try-catch로 예외 처리하기

이번에는 try...catch 블록을 사용해 이 오류를 처리해 보겠습니다. 오류가 발생하면 "There was an error"라는 메시지를 출력하도록 하여, 문제가 발생했음을 인지할 수 있게 만들겠습니다.

class Main {
public static void main(String[] args) {
    try {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
} catch (Exception e) {
    System.out.println("There was an error.");
        }
}

이제 코드를 실행하면 다음과 같은 결과가 출력됩니다.

There was an error.

여러 catch 블록 사용하기

하나의 try 블록에 여러 개의 catch 블록을 지정할 수도 있습니다. 이렇게 하면 예외의 종류에 따라 각각 다르게 대응할 수 있다는 장점이 있습니다.

위 예제에서는 ArrayIndexOutOfBoundsException이 발생했습니다. 만약 이 특정 오류만 별도의 메시지로 처리하고, 그 외의 일반적인 예외는 다른 방식으로 처리하고 싶다면 여러 개의 catch 문을 사용하면 됩니다.

다음은 ArrayIndexOutOfBoundsException과 일반 Exception을 모두 검사하고, 각 오류에 맞는 맞춤 응답을 출력하는 프로그램 예제입니다.

class Main {
public static void main(String[] args) {
    try {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("ArrayIndexOutOfBoundsException was raised.");
} catch (Exception e) {
    System.out.println("There was an error.");
        }
}
}

이 프로그램을 실행하면 콘솔에 다음 메시지가 출력됩니다.

ArrayIndexOutOfBoundsException was raised.

프로그램에서 ArrayIndexOutOfBoundsException이 발생했기 때문에 해당 예외에 맞는 catch 블록이 실행된 것입니다. 만약 다른 종류의 오류가 발생했다면 Exception e catch 블록의 코드가 실행되어 다음 메시지가 출력될 것입니다.

There was an error.

finally 문 활용하기

finally 문은 try...catch 블록의 실행이 끝난 후 특정 코드 블록을 실행할 때 사용합니다. finally 블록은 선택 사항이지만, 한 번 정의되면 항상 실행됩니다. 예외가 발생하지 않으면 try 블록 실행 후에, 예외가 발생하면 catch 블록 실행 후에 호출됩니다.

앞선 예제에 finally 문을 추가해 실제 동작을 확인해 보겠습니다. try...catch 문이 완료되었음을 알려주기 위해 "This block has finished executing"이라는 메시지를 콘솔에 출력한다고 가정해 보겠습니다.

class Main {
public static void main(String[] args) {
    try {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("ArrayIndexOutOfBoundsException was raised.");
} catch (Exception e) {
    System.out.println("There was an error.");
        } finally {
            System.out.println("This block of code has finished executing.");
        }
}
}

이 코드를 실행하면 다음과 같은 결과가 출력됩니다.

ArrayIndexOutOfBoundsException was raised.
This block of code has finished executing.

실행 결과를 보면 앞서와 마찬가지로 ArrayIndexOutOfBoundsException 예외가 발생했고, 해당 예외에 맞는 catch 블록의 코드가 실행되었습니다.

그리고 finally 문을 지정했기 때문에, catch 블록이 실행된 후 "This block of code has finished executing" 메시지가 추가로 출력된 것을 확인할 수 있습니다.

마무리

Java에서 try...catch 블록은 예외를 우아하게(gracefully) 처리하기 위해 사용됩니다. try 블록 안의 코드가 실행되고, 예외가 발생하면 해당 예외에 맞는 catch 블록의 코드가 실행됩니다. 또한 finally 문을 사용하면 예외 발생 여부와 관계없이 try...catch 블록 실행 후 반드시 실행해야 하는 코드를 작성할 수 있습니다.

이 글에서는 Java에서 try...catch 블록으로 예외를 처리하는 방법과 finally 블록의 사용법을 살펴보았으며, 두 구문을 활용해 오류를 처리하는 실제 예제도 함께 다루었습니다.

이제 여러분은 Java에서 자신 있게 예외를 처리할 수 있는 준비를 마쳤습니다!