Java/계산기 구현

3단계 계산기 - try-catch 문을 사용한 예외처리

JuNo_12 2025. 4. 22. 15:43

전 내용과 이어집니다.

public static Operator fromSymbol(char symbol) { // 연산자 기호를 받아서 해당하는 Operator enum 값을 반환. 일치하는 것이 없으면 예외 처리
    for (Operator op : Operator.values()) {
        if (op.symbol == symbol) {
            return op;
        }
    }
    throw new IllegalArgumentException("지원하지 않는 연산자입니다.");
}

 

이 부분이 원래 throw new 가 아니라 return null; 이였다. 입력 받은 문자열이 저장된 사칙연산기호가 아니라면 null을 반환해주는 시스템이였는데, 이건 굉장히 잘못된 방법이였다. null을 직접 반환한다는 것이 굉장히 안좋은 거고 절대로 해서는 안될 짓이라고 들었는데... 왜냐하면 NullPointerException이 발생할 수 있기 때문이다.

 

NullPointerException 이란?

: null인 객체를 참조하려고 할 때 발생하는 예외

 

  • null 값을 가진 객체에 메서드 호출하거나
  • null인 배열에 접근하거나
  • null인 컬렉션에서 작업하려고 할 때

왜 위험하냐면,

 

  • 예외 발생 위치를 추적하기 어려울 수 있다.
  • 코드 흐름을 예측하지 못하게 한다.
  • 잘못 처리하면 프로그램이 중단될 수 있다.

 

 

그래서 Optional을 사용해서 null을 안전하게 처리해주어야한다.


 

우선 이 부분은 뒤에서 자세히 살펴보고, 지금은 try-catch문을 사용해서 예외처리 하는 방법에 집중해보자.

public static Operator fromSymbol(char symbol) { // 연산자 기호를 받아서 해당하는 Operator enum 값을 반환. 일치하는 것이 없으면 예외 처리
    for (Operator op : Operator.values()) {
        if (op.symbol == symbol) {
            return op;
        }
    }
    throw new IllegalArgumentException("지원하지 않는 연산자입니다.");
}

 

throw new는 자바에서 예외를 '직접' 발생시키는 키워드이다. 내가 원할 때 예외를 강제로 발생시키고 싶을 때 사용한다.

 

try {
    double result = executor.execute(inputNumber1, inputNumber2, operator);
    System.out.println("계산 결과 : " + result);
    break;
} catch (IllegalArgumentException e) {
    System.out.println(e.getMessage());
}

이 코드는 메인 클래스에서 작성한 내용인데,

try{ ... }

블록 안의 코드는 "예외가 발생할 수도 있는 코드"를 넣는 부분이다.

만약 내가 저장해 둔 연산자기호가 아닌 다른 문자열을 입력받으면 IllegalArgumentException이 발생할 수 있기에 예외가 생길 수도 있다는 걸 미리 감지해서 try 블록으로 감싸놓은 것이다.

catch (IllegalArgumentException e) { ... }

try 블록에서 IllegalArgumentException 이 바래생시에 이 catch 블록으로 바로 이동한다.

예외를 e라는 이름으로 받아서, 그 안에 담긴 메세지를 출력할 수 있도록 했다.

 

System.out.println(e.getMessage());

 IllegalArgumentException 내부에 담긴 오류 메세지를 출력한다.

 

 

여기까지는 별로 어려운 내용이 없다. 하지만, Optional을 이용한 null처리는 굉장히 어려웠고 지금도 어렵다...

하지만 꼭! 알아야되는 내용이기에 천천히 알아가보자.


Optional을 활용해서 null을 안전하게 처리해보자.

위에서 NullPointerExeption에 대해 간단하게 알아보았다.

Optional은 예외를 직접적으로 "처리"하는 도구는 아니고, null이 들어올 수도 있는 상황을 안전하게 다루기 위한 도구이다.

정리하자면, null 값이 발생할 수 있는 상황을 '명시적'으로 표현하고, NullPointerExeption을 피할 수 있도록 도와주는 컨테이너 객체이다. 

상황 사용 여부
메서드에서 null을 반환할 수 있다면 Optional로 감싸서 반환하는 것이 더 안전하고 명확하다.
메서드에서 반드시 값이 있어야 하고, 없으면 에러여야 한다면 Optional보다 예외(throw)를 던지는 게 더 적절할 수 있다.
필수적인 필드라서 무조건 값이 있어야 한다면  Optional로 만들면 혼란을 줄 수 있다. 그냥 일반 타입을 써야 한다.
복잡한 if-else 없이, 간결하게 fallback 값을 주고 싶을 때 Optional.orElse, orElseGet, ifPresent 등을 활용할 수 있다.

 

하지만, 내가 작성한 코드에서는 무조건적으로 사칙 연산자를 입력 받아야한다. 그렇다면 메서드에 반드시 값이 존재한다는 것.

따라서 Optinal을 사용 안해주어도된다. 내가 여기서 왜 Optional을 다시 한 번 공부하려고했냐면, 이전 코드에서 내가 return null;을 해주었는데 이를 바로 잡기 위해서 Optional을 사용하여 처리를 해주려고 했기때문이다. 하지만, try-catch문으로 예외처리를 해주었고, null을 반환해주는 것 대신에 throw new 를 사용함으로써 해결했다.

 

중요한 점은, null을 '직접' 다루면 절대절대절대 안된다. 절대로. 절대절대절대.