[Java] try - catch - finally 의 사용법 with Spring boot

2025. 1. 3. 23:15프로그래밍 언어/Java

개요

프로그래밍을 진행 중 간단한 문제가 발생하면 알려주는 Exception 클래스가 있다.

많이 보지만 실제로 이게 왜 발생하는지 찾을 수 없거나 혹은 찾아도 왜 나는 지 모르는 경우가 종종 있다.

Java 에서는 확인된 문제들을 Exception으로 예외를 처리를 할 수 있게 해주는 try - catch - finally 문법이 있다

 

이 게시물에서는 try - catch - finally 문법에 대해서 자세히 알아보자.

 

 

Error VS Exception

가장 먼저 "Error 와 Exception은 다르다" 라는 것을 알고 가야한다.

  • Error
    • 시스템 레벨 혹은 환경적인 이유로 발생
    • 코드 문제도 있지만 발생하는 경우 프로그램이 종료가 되게 된다.
  • Exception
    • 예외는 회복이 가능하다는 전제가 붙는다.
    • 코드 레벨에서 해결할 수 있는 문제 상황에 대한 대응은 예외처리에 속한다.

 

예외의 종류

  • 컴파일 예외
    • .java 를 .class 로 컴파일할 때 발생
    • 프로그래밍 규칙을 지키지 않아서
  • 런타임 예외
    • 문법적 오류가 아님.
    • 컴파일은 잘됨
    • 논리적 오류 등으로 발생함

 

런타임 예외는 그러면 어떤 것이 있는가?

  • 확인된 예외 ( Checked Exception )
    • 컴파일 시점에 확인하는 예외
    • 현재 프로그램의 제어 밖에 있는 예외
    • RuntimeException을 상속하지 않는 예외
  • 미획인된 예외 ( Unchecked Exception )
    • 컴파일 시점에 확인되는 예외
    • 프로그램 로직의 오류로 인한 예외들
    • RuntimeException을 상속하는 예외

 

그렇다면 이런 예외를 직접 확인을 해보자.

package JavaTest;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        String str = scanner.nextLine();

        int num = Integer.parseInt(str);

        System.out.println(num);
    }
}

숫자 10 입력
a1234 입력

 

위의 코드를 확인을 해보면 사용자가 숫자만 입력을 하면 문제가 없는 코드이다.

하지만 사용자가 숫자( Integer ) 가 아닌 값을 입력을 했다면 NumberFormatException 이 발생을 하게 되는 것이다.

이것은 백엔드 개발 중에도 확인을 할 수 있는 모습이다

 

만약에 UserDTO을 입력을 받아야되는데 입력 받는 값이 UserDTO가 아니라면

서버에서 잘못된 값을 입력을 받았다는 Exception이 발생을 하게 될 것이다.

 

이제 try - catch - finally을 사용을 해보도록 하자.

package JavaTest;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        try {
            System.out.println("일단 실행");
            String str = scanner.nextLine();

            int num = Integer.parseInt(str);
            System.out.println(num);
        } catch (Exception e) {
            System.out.println("에러 발생");
        } finally {
            System.out.println("마무리");
        }
    }
}

에러 회피

간단하게 try - catch - finally 문법을 사용해 보았다.

 

소스 코드를 확인을 해보면 기존 코드를 전부 try {} 안에 넣은 모습을 확인을 할 수 있다.

사용자가 a1234를 입력을 했을 때, NumberFotmatException이 발생을 하는 것이 아닌

"에러 발생" 이라고 출력이 되는 모습을 확인을 할 수 있다.

 

마지막으로 "마무리" 가 나오는데 앞서 try - catch 문에서 발생할 수 있는 예외 상태를 코드상으로 해결을 하고

마지막에 실행이 되는 모습을 확인할 수 있다.

다시 코드로 확인을 해보면 다음과 같다.

package JavaTest;

public class Main {
    public static void main(String[] args) {
        try {
            // 예외가 발생할 수 있는 코드
        } catch (/*예외처리를 처리할 예외 클래스*/) {
            // 예외가 발생하면 실행이 될 코드
        } finally {
            // 마지막에 실행이 되는 코드
        }
    }
}

 

 

try - catch - finally 를 적용해보자.

@RestController
public class TestController {

    @GetMapping("/test/test3")
    public String tempTest(QuestionDTO questionDTO) {

        QuestionEntity questionEntity;
        try {
            if( questionDTO.getQuestion().isEmpty() ) throw new Exception();
            questionEntity = QuestionEntity.builder()
                    .question(questionDTO.getQuestion())
                    .category(questionDTO.getCategory())
                    .build();
        } catch ( Exception e ) {
            System.out.println("인풋 에러");
            return "인풋에러";
        } finally {
            System.out.println(
                    "/test/test3 동작" +'\n' +
                            "finally 동작"
            );
        }

        return questionEntity.toString();
    }
}

 

단순하게 사용을 해보았다.

QuestionDTO -> QuestionEntity 로 넘어가는 과정에서 내용이 비어있다면 Exception 이 발동이 되어서

밑 catch족으로 넘어가는 모습을 확인 할 수 있다.

 

 

 

느낀점

오늘 try - catch - finally 강의를 들으면서 튜터님이 초심자들이 개발을 하다보면 기능 구현이 우선 시가 되어서

예외처리를 생각하지 않고 개발을 하게 되지 않는다는 말을 하셨다.

 

근대 이게 내 뼈를 때리는 말이라서 당장 스프링 쪽에 붙여서 사용을 해보려고 노력을 하였다.

 

이제 실제로 프로젝트에 적용을 해보면서 예외처리도 많이 연습을 해봐야겠다고 생각을 했다.