[ JAVA] try-catch-finally

JHJeong·2024년 4월 10일
0

오류와 예외는 JAVA 프로그램 실행 중 발행할 수 있는 문제점들을 나타내지만, 그 성격과 대응 방법에 있어서 차이가 있다.

Error(오류)

  • 시스템 레벨에서 심각한 문제를 나타낸다.
    ( 예를 들어 "OutOfMemoryError", "StackOverflowError" 와 같은 에러 )
  • 이러한 오류들을 대부분 프로그램의 제어를 벗어난 상황에서 발생하며, 애플리케이션이 이를 복구할 수 없는 심각한 문제들이다.
  • 오류는 "java.lang.Error" 클래스의 서브 클래스들로 표현된다.

Exception(예외)

  • 프로그램 실행 중에 발생할 수 있는, 비교적 덜 심각한 문제들을 나타낸다.
  • 검사된 예외(checked exceptions)와 검사되지 않은 예외(unchecked exceptions)로 구분된다.
  • 검사된 예외(checked exceptions) : 명시적인 예외 처리가 필요한 예외들이다. 이들은 "Exception" 클래스를 상속하지만, "RuntimeException"을 상속하지 않는다.
    ( 예를 들어, IOException이나 SQLException 등이 있다. 이 예외들은 컴파일 시점에 처리 여부를 검사한다.)
  • 검사되지 않은 예외 (Unchecked Exceptions) : 명시적인 예외 처리를 강제하지 않는 예외들이다. 이들은 RuntimeException과 그 서브클래스들입니다.
    ( 예를 들어, NullPointerException, IndexOutOfBoundsException 등이 있다. 이 예외들은 대부분 프로그램의 버그로 인해 발생하며, 런타임 시점에 발생한다. )

try-catch-finally문

  • try-catch-finally 문은 예외 처리를 위한 기본 구조이다.
  • try 블록 내에서 예외가 발생할 수 있는 코드를 배치한다. 예외가 발생하면, catch 블록이 실행되어 해당 예외를 처리한다. finally 블록은 예외 발생 여부와 관계없이 항상 실행되며, 주로 리소스를 해제하는 코드를 포함하게된다.
try {
    // 예외 발생 가능 코드
} catch (ExceptionType e) {
    // 예외 처리 코드
} finally {
    // 리소스 해제 등의 정리 코드
}

여기서 return이 catch블록이나 finally블록에 있는 경우에는 어떻게 될까?
먼저 catch 블록안에 return문이 있는 경우이다.

public class CatchReturnExample {
    public static int testMethod(int num) {
        try {
            System.out.println("Inside try block");
            if( num == 1 ) {
                throw new RuntimeException("Test Exception");
            }
        } catch (RuntimeException e) {
            System.out.println("Inside catch block");
            return 1;
        } finally {
            System.out.println("Inside finally block");
        }
        return 0;
    }

    public static void main(String[] args) {
        int result = testMethod(1);
        System.out.println("Result: " + result);
        int result2 = testMethod(2);
        System.out.println("Result: " + result2);
    }
}

실행 결과
Inside try block
Inside catch block
Inside finally block
Result: 1
Inside try block
Inside finally block
Result: 0

위 처럼 catch블록이 실행되도록 RuntimeException의 예외를 발생 시킨 경우에 catch 블록에서 return을 실행했지만 finally 블록이 실행 된 후에 catch블록에서의 return 값인 1을 리턴하게 된다.

그럼 아래처럼 finally 블록안에 return문이 있는 경우에는 어떻게 실행될까?

public class CatchReturnExample {
    public static int testMethod(int num) {
        try {
            System.out.println("Inside try block");
            if( num == 1 ) {
                throw new RuntimeException("Test Exception");
            }
        } catch (RuntimeException e) {
            System.out.println("Inside catch block");
            return 1;
        } finally {
            System.out.println("Inside finally block");
            return 2;
        }
    }

    public static void main(String[] args) {
        int result = testMethod(1);
        System.out.println("Result: " + result);
        int result2 = testMethod(2);
        System.out.println("Result: " + result2);
    }
}

출력 결과
Inside try block
Inside catch block
Inside finally block
Result: 2
Inside try block
Inside finally block
Result: 2

소스 코드를 보면 finally 블록 내에 return문이 있고 catch문 안에도 return문이 있다. 하지만 출력 결과는 catch 블록을 실행하든 하지않든, return 값은 2로 finally 블록에서 리턴하도록 되어있다.

finally 블록에서 return을 사용하는 것은 특별한 경우를 제외하고는 권장되지 않는다. 이는 try 또는 catch 블록의 return 문을 덮어쓰기 때문에 코드의 흐름을 예측하기 어렵게 만들고, 따라서 버그의 원인이 될 수 있기 때문이다. 가능한 한, 모든 메소드에서 단일 return 지점을 유지하는 것이 좋은 프로그래밍 습관이기 때문에, 소스는 보기 편하도록 짜는 습관을 들이도록 하자.

throw 문

  • throw 문은 프로그래머가 의도적으로 예외를 발생시키고자 할 때 사용된다. 이를 통해 생성된 예외는 적절한 catch 블록에서 처리될 수 있다.
if (someCondition) {
    throw new ExceptionType("Error Message");
}
profile
이것저것하고 싶은 개발자

0개의 댓글