Java sealed 클래스, 모듈 경계 넘으면 런타임 오류로 이어질 수 있어

Java sealed classes and exhaustive pattern matching

Java 17의 sealed 클래스는 switch 문에서 default 없이도 모든 경우를 컴파일 타임에 검사하는 장점을 제공한다. 하지만 sealed 타입을 라이브러리 API로 노출하면 새로운 하위 타입 추가가 곧 breaking change가 된다. 특히 소비자가 재컴파일되지 않으면 컴파일 오류 대신 런타임에 MatchException이 발생할 수 있다. 저자는 sealed 타입이 컴포넌트 내부 구현에는 유용하지만 공개 API에는 부적합하다고 결론짓는다.

sealed 타입을 API로 내보낸다면 새로운 하위 타입을 추가하는 것은 메이저 버전 범프가 필요한 breaking change가 된다.
  1. shepherdjerred

    Java가 여기까지 발전한 게 정말 마음에 듭니다. 그래도 저는 프론트엔드 작업을 많이 하고 스택 전체에서 같은 언어를 쓰는 걸 선호해서 TypeScript를 여전히 더 좋아합니다.

    그렇긴 해도, TypeScript에서도 완전한(exhaustive) 패턴 매칭을 할 수 있습니다! https://github.com/gvergnaud/ts-pattern

  2. armchairhacker

    Java에는 재귀 패턴과 (아마 아직 프리뷰일) 리터럴 패턴도 있습니다: `switch (x) { case A(B(true, var c)) -> f(c); }`

  3. another_twist

    sealed에 익숙해지는 데 시간이 좀 걸렸고 그 용도를 잘 못 봤습니다. 그런데 AI가 Java에서 이걸 무척 좋아하는 것 같아서 한번 써봤더니 이제 이해가 됩니다. 특히 DI를 쓰고 뭔가를 deprecated 처리하고 싶을 때 정말 좋은 접근 제어 메커니즘이더군요. 물론 패턴 매칭은 말할 것도 없고요 — 페이로드 형태가 바뀌는 이벤트 기반 메시지에서 유용합니다.

  4. timshel2

    Scala가 지금 허공에 주먹을 휘두르고 있겠네요

  5. panny

    sealed 타입에서는 저 switch default들이 필요 없다고 생각합니다. 컴파일러로 확인해보진 않았지만 불필요하다고 봅니다.

  6. Larrikin

    Java는 계속 Kotlin을 따라잡으려고 애쓰고 있네요

    https://kotlinlang.org/docs/sealed-classes.html

    비교 대상이 C++, Ruby, Python이던 시절엔 Java도 괜찮았습니다. 하지만 Scala(무차별적이라 실패한 것처럼 보였죠), 특히 Kotlin을 거친 뒤에는 다시 돌아갈 이유를 찾을 수가 없습니다

이 날의 다른 글

2026-10-18