2022년 토이 프로젝트의 개발 환경을 정하면서 Java 버전별 차이를 찾아봤다. 당시에는 Java 17이 최신 LTS였고, record와 sealed class를 직접 써 보고 싶다는 이유도 있었다.
몇 년이 지나 버전 표가 달라졌고, 당시 메모에는 preview 기능과 정식 기능이 섞여 있었다. 2026년 8월 기준으로 다시 정리하면 결론은 단순하다. 새 프로젝트는 가장 최신 버전보다 팀과 운영 환경이 끝까지 지원할 수 있는 LTS를 우선 검토한다. 현재 Oracle 기준 최신 LTS는 Java 25이고, 최신 feature release는 Java 26이다.
Java LTS는 무엇을 뜻하나
LTS(Long-Term Support)는 Java 언어 사양에 별도의 안정성 등급이 있다는 뜻이 아니다. 특정 JDK 공급자가 그 release를 장기간 유지·지원하겠다는 정책이다. 따라서 “Java 25 LTS를 쓴다”는 결정만으로는 충분하지 않다.
- Oracle JDK, Eclipse Temurin, Amazon Corretto처럼 어떤 distribution을 쓸지
- 무료 update와 상용 support의 범위가 어디까지인지
- framework, library, build tool, monitoring agent가 그 version을 지원하는지
- container base image와 배포 runtime을 같은 patch level로 관리할 수 있는지
Oracle의 현재 roadmap에서 LTS release는 8, 11, 17, 21, 25다. Java는 6개월 주기로 feature release가 나오며, non-LTS release는 다음 feature release가 나오면 빠르게 대체된다. 운영 환경에서 LTS를 먼저 보는 이유는 기능 수보다 update를 받을 수 있는 기간과 생태계 호환성 때문이다.
버전별로 기억할 변화
모든 변경을 외우기보다 코드 작성 방식이 크게 달라진 지점만 묶어 두는 편이 유용했다.
| 버전 | 구분 | 기억할 변화 |
|---|---|---|
| 8 | LTS | lambda, Stream API, interface default method, java.time |
| 9 | non-LTS | module system, JShell |
| 10 | non-LTS | local variable type inference인 var |
| 11 | LTS | HTTP Client 표준화, Java EE·CORBA module 제거 |
| 14 | non-LTS | switch expression 정식 기능, record preview |
| 15 | non-LTS | text block 정식 기능, sealed class preview |
| 16 | non-LTS | record 정식 기능, instanceof pattern matching 정식 기능 |
| 17 | LTS | sealed class 정식 기능 |
| 21 | LTS | virtual thread, record pattern, switch pattern matching, sequenced collection |
| 25 | LTS | 2026년 8월 기준 최신 LTS |
| 26 | non-LTS | 2026년 3월 공개된 최신 feature release |
당시 “Java 14의 record, Java 15의 sealed class”라고 적었던 것은 틀린 표현은 아니지만 정확하지 않았다. 두 기능은 각각 그 버전에서 preview로 들어왔고, record는 Java 16, sealed class는 Java 17에서 정식 기능이 됐다. 실제 제품 코드에 적용할 때는 기능이 처음 보인 버전보다 정식 확정된 버전을 확인해야 한다.
새 프로젝트에서 Java 버전을 고르는 순서
1. 배포 대상이 지원하는 범위를 먼저 확인한다
local에서 실행된다는 사실보다 production runtime이 더 중요하다. 사용하는 Spring Boot·application server·database driver·APM agent·cloud runtime의 지원표를 먼저 확인한다. 하나라도 목표 version을 지원하지 않으면 upgrade 비용이 생긴다.
2. 지원 가능한 LTS 중 가장 높은 버전을 검토한다
특별한 제약이 없다면 현재 지원되는 LTS부터 검토한다. 다만 “최신 LTS이므로 무조건 선택”이 아니라, team이 patch update와 regression test까지 지속할 수 있는지가 기준이다. 기존 system은 현재 version의 보안 update 종료일과 migration 비용을 함께 본다.
3. compile JDK와 실행 대상 version을 구분한다
개발자가 최신 JDK를 쓰더라도 산출물은 더 낮은 Java version을 대상으로 만들 수 있다. 단순히 sourceCompatibility만 낮추면 새 JDK API를 실수로 참조할 수 있으므로 compiler의 --release 또는 build toolchain을 명시하는 편이 안전하다.
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}
tasks.withType(JavaCompile).configureEach {
options.release = 21
}
이 예시는 JDK 25 toolchain으로 compile하되 Java 21 API와 class-file target에 맞추는 경우다. 실제 값은 배포 runtime에 맞춰야 한다.
4. 새 기능은 목적이 있을 때 선택한다
record나 sealed class를 써 보고 싶다는 동기는 학습용 토이 프로젝트에서는 충분히 의미가 있다. 반면 운영 project에서는 syntax의 편리함뿐 아니라 팀 숙련도, serialization framework, proxy, test 도구의 호환성까지 확인해야 한다. virtual thread도 I/O 중심 workload에서 검토할 선택지이지, 기존 code를 바꾸기만 하면 모든 처리량 문제가 사라지는 기능은 아니다.
당시 선택을 지금 다시 본다면
2022년에는 최신 LTS였던 Java 17을 고르려 한 방향이 자연스러웠다. record와 sealed class를 정식 기능으로 함께 사용할 수 있다는 점도 목적에 맞았다.
지금 새 토이 프로젝트를 시작한다면 Java 25 LTS를 먼저 검토하되, 사용하려는 framework와 배포 환경이 아직 Java 21까지만 검증됐다면 21을 택하겠다. 핵심은 version 숫자를 높이는 것이 아니라 지원 기간, 호환성, 배포 환경, 학습 목적을 한 문장으로 설명할 수 있는 선택이다.
기초 문법을 다시 훑을 때 적은 내용은 W3Schools Java tutorial 학습 노트에, 언어의 관용적인 사용을 고민한 내용은 자바답게 프로그래밍하기에 이어 정리해 두었다.
참고 자료
'배움과 성장 > 소프트웨어 개발' 카테고리의 다른 글
| Python 변수 스왑: a, b = b, a의 평가 순서와 주의점 (0) | 2024.03.30 |
|---|---|
| 클린 아키텍처 학습 메모: 정책 수준과 의존성 방향 (0) | 2022.12.30 |
| 자바답게 프로그래밍한다는 질문이 남긴 것 (0) | 2022.10.31 |
| W3Schools Java 튜토리얼 복습: 추상 클래스·인터페이스·컬렉션 (0) | 2022.10.20 |
| Java 생성자와 빌더: 무조건 Builder가 정답은 아니었다 (0) | 2022.10.18 |
댓글