-
Java Exception Handling (e.printStackTrace())JAVA/자바공부 2023. 10. 20. 01:20
업무 중 코파일럿에 의해 Exception catch문과 e.printStackTrace()가 자동으로 생성되는 일이 있었다.
팀장님의 이거 쓰면 안되요! 라는 리뷰가 달렸는데, 왜 안될까?
Exception이란 무엇일까?e.printStackTrace의 정체는 무얼까?
Exception 정의
- 프로그램 실행중 정상적인 흐름을 방해하는 이벤트
- 일반적으로 Exception이 발생하면 현재 코드 블럭이나 메서드의 동작이 멈춘다.
Exception의 역사
- 약 40년 전 최초 프로그래밍 언어에는 Exception이라는 개념이 없었다.
- C 언어에서는 비정상적인 종료를 알리고자 -1 또는 null을 반환하는 방식으로 동작했다.
- 함수를 호출하고 실수로 -1, null 값 확인을 놓치는 실수들이 속출
- 1985년, C++ 언어가 등장해 C의 문제를 해결하기 위해 Exception이라는 개념을 사용했다.
- 비정상적인 종료가 발생하면 어디서 프로그램이 종료했는지 call stack을 쌓았다.
- 그러나, 어떤 함수가 정확히 어떤 예외를 던지는지 알아 볼 수 없는 문제가 있었다.
- 1995년, Java 등장 비정상적인 종료를 잡아내기 위해, 특정 함수에서 어떤 Exception이 발생하는지 Checked Exception 개념을 도입
- recoverable한 예외에 한해서 Checked Exception을 던질 수 있게 되었다.
Java의 Exception 계층
java.lang.Throwable; // 예외 최상위 클래스 java.lang.Error; // JVM의 low-level exceptiom 데표 (ex. OutOfMemoryError, StackOverflowError) java.lang.Exception; // app 내부의 예외 event (ex. RuntimeException, IOException)
- 모든 예외는 최상위 부모 Throwable을 상속한다. (아래 3개의 기본 메서드를 사용할 수 있다.)
- String getMessage(); returns the detailed string message of this exception object;
- Throwable getCause(); returns the cause of this exception or null if the cause is nonexistent or unknown;
- printStackTrace(); prints the stack trace on the standard error stream.
Checked Exception vs Unchecked Exception
- 컴파일러의 시선에서 2가지로 나뉜다.
- Checked Exception
- 컴파일러가 checked 가능한 에러 java.lang.Exception; (RuntimeException 자식 클래스를 제외한 모든 Exception)
- Checked Exception에는 메서드() 뒤에 throws 선언과 try-catch를 의무적으로 사용해야한다. (안쓰면 컴파일 에러)
- Checked Exception
class Config { public static Date getLastPromoDate() throws ParseException, IOException { Properties props = new Properties(); try (Reader reader = new FileReader("config.properties")) { props.load(reader); } SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); return format.parse(props.getProperty("last.promo.date")); } }
- Unchecked Exception
- 프로그램 실행중 발생하는 컴파일러가 check 불가한 에러이다.
- RuntimeException과 그 자손 예외 클래스
RuntimeException을 상속 커스텀해서 사용하자
- 현대 Web에서는 UncheckedException 사용이 권장 된다.
- checked exception은 현대 개발 환경에 맞지 않다. 분산 환경에서 외부 시스템, 수 많은 라이브러리에서 checked exception을 사용한다고 상상해보자. checked exception은 메서드에 throws를 선언하고 try-catch가 필수적으로 필요하다. 즉 구현 계층에 외부 의존성이 생긴다.
- Checked Exception은 복구 불가한 에러이다. 개발자가 직접적으로 컨트롤하지 않는다.
- Checked Exception으로 개발하면 catch 문을 비워두는 사례 자주 생기는데 이는 지양한다. (Diaper Pattern으로 이름도 있음)
public void applyDiscount(Order order, Customer customer) { try { if (order.getOfferDate().before(Config.getLastPromoDate())) { System.out.println("APPLYING DISCOUNT"); order.setPrice(order.getPrice() * (100 - 2 * customer.getMemberCard().getFidelityDiscount()) / 100); } else { System.out.println("NO DISCOUNT"); } } catch (Exception e) { // TODO <- 나중에 어떤 에러 던지려 했었는지 까먹거나, 작성자가 퇴사함 } }
결론
- RuntimeException을 커스텀해서 잘 사용해보자
- e.printStackTrace()는 Throwable 객체에서 제공하는 exception call stack이다.
- e.printStackTrace()를 사용하면 log file에 Error가 쌓이지 않기 때문에 쓰면 안된다.
참고
반응형'JAVA > 자바공부' 카테고리의 다른 글
JAVA 함수형 프로그래밍 (1) - Functional Interface (0) 2024.08.16 자바 LocalDateTime 요일, 오전/오후 한국어로 변경 (0) 2023.08.03 (다시 보는) SOLID 원칙이란? (0) 2023.05.29 DB의 시간, Java의 시간, Javascript의 시간 (Data, LocalDate, LocalDateTime, Y2K38 Problem) (2) 2023.03.07 자바 (0) 2023.02.20