JAVA 8/11/17/21 버전 별 변화와 LTS에 대해
들어가며
안녕하세요, 개발자 비니입니다.
면접이라던지, 종종 JAVA를 사용하는 기업들에서 "JAVA x버전은 왜 쓰죠?"라는 말이
종종 나오고 있는 것 같아요.
저도 이에 명쾌하게 답을 못 했어서,
이 참에 뭔지 스스로 정리할 겸 기록을 남겨보고자 합니다.
LTS란?
Long Term Support
말 그대로 "장기 지원 버전" 이라는 뜻이긴 합니다.
하지만 정확히 말해서, 저는 "일반 기간보다 더 오래 지원하도록 하는 버전"이라 생각합니다.
여기서 지원한다는 말은, 새로운 기술을 넣는다는 것보단,
발생하는 버그를 수정하고, 유지보수 해 준다는 말입니다.
대표적으로
JAVA 8 / 11 / 17 / 21 들이 LTS입니다.
💫 "왜 LTS를 주로 사용하나요?"
JAVA는 많은 사람들에게 사랑받고, 사용되어오고 있죠.
하지만 "모든 버전이 LTS를 지원하지는 않아요".
JAVA 버전이 올라갈 수록 개발자들에게 새로운 기능을 제공하는데,
LTS를 제공하지 않는 버전의 경우엔 기업 환경이나 대규모 프로젝트에서 사용하기 꺼려집니다.
만약, 프로젝트를 개발하던 중 "심각한 보안 이슈나 버그가 발생하는 버전"을 사용하고 있었는데,
LTS가 아닌 버전이고, "지원이 중단 된 버전이라면?"
프로젝트를 새로운 버전으로 마이그레이션 해야 하는 상황에 이릅니다.
"안정성"과 "신뢰성"이 중요한 기업 환경과 큰 프로젝트에서 많이 선호되고,
같은 이유로 많은 개발자들에게 선택받게 됩니다.
💨 "Spring Boot와의 연관성이 있나요?"
네! Spring Boot의 버전에 따라서 지원하는 Java 버전이 다릅니다.
프로젝트가 만약 Spring Boot 기준이라면, Java 버전도 고려해야 해요!
Spring Boot 2.x을 사용하면, "Java 8"을 사용합니다.
Spring Boot 2.1+부턴 "Java 11"을 사용합니다.
Spring Boot 3.x 부터는 "Java 17"을 사용합니다. (현재!)
3.x 이후 버전은 "Java 21"을 모두 지원합니다.
다시 정리하면,
Spring Boot 2.x
- Java 8 또는 11 사용을 권장.
Spring Boot 3.x
- 최소 Java 17 이 필요.
미래를 대비한 개발
- Java 21을 선택하여 향후 업데이트를 준비하자.
물론, 그렇다고 항상 LTS가 정답이란 말은 아닙니다.
LTS가 아닌 일반 버전도 최신 기능과 개선 사항을 중시하면, 일반 버전이 더 적합해요!
업데이트를 더 자주 해야 하긴 하지만, 신 기능들을 적극적으로 쓸 수 있는 거죠.
JAVA 8
JAVA 8은 2014년 3월에 오픈되었습니다. 그리고..
"자바의 새 시대를 연 버전"으로 평가받습니다.
함수형 프로그래밍과 스트림 API 같은 강력한 기능들이 추가되면서 개발 경험이 한 단계 진화했기 때문인데,
지금도 레거시 프로젝트에서 널리 사용되고 있습니다.
1. 람다식 지원
Lamda Expressions
메서드를 하나의 식으로 표현할 수 있는 기능입니다.
이 기능이, JAVA를 함수형 프로그래밍으로 도약하는 큰 기능이 되었습니다.
덕분에 불필요한 코드를 줄이고, 높은 가독성을 얻을 수 있었어요.
💫 "버튼을 클릭하는 기능을 만들어야 할 때"
1. 과거 (람다식 미 지원 버전)
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("버튼 클릭됨!");
}
});
2. 현재 (Java 8 이상)
button.setOnClickListener(v -> System.out.println("버튼 클릭됨!"));
💫 "간단한 덧셈 연산을 할 때"
1. 과거 (람다식 미 지원 버전)
public interface Calculator {
int add(int a, int b);
}
Calculator calc = new Calculator() {
@Override
public int add(int a, int b) {
return a + b;
}
};
System.out.println(calc.add(3, 5));
2. 현재 (Java 8 이상)
Calculator calc = (a, b) -> a + b;
System.out.println(calc.add(3, 5));
익명 클래스의 반복적인 코드를 제거하고, 필요한 로직만 표현하도록 만들어줍니다.
쉽게 말해서, "함수 자체를 데이터처럼!"을 실현하는 것이죠.
2. Optional 클래스 제공
NullPointerException 문제를 처리할 수 있는 형식입니다.
Null을 수동으로 체크하고, 실수로 휴먼에러로 놓치면 바로 NullpointerException이 발생하는 거죠.
💫 "이름을 읽는 경우"
1. 과거 (람다식 미 지원 버전)
String name = getName();
if (name != null) {
System.out.println(name);
} else {
System.out.println("Name is null");
}
2. 현재 (Java 8 이상)
Optional<String> name = Optional.ofNullable(getName());
name.ifPresentOrElse(
System.out::println,
() -> System.out.println("Name is null")
);
코드만 봤을 때 더 헷갈릴 수는 있지만,
휴먼에러를 줄이는 좋은 기능입니다.
3. Stream API 제공
컬렉션(List, Map 등) 데이터를 처리할 때, 과거에는 반복문이나 조건문을 사용해 직접 데이터를 다뤘습니다.
굉장히.. 불편했어요. 이제는. Stream() 하나로 쉽게 만들 수 있게 되었습니다.
💫 "이름을 읽는 경우"
1. 과거 (람다식 미 지원 버전)
List<String> names = Arrays.asList("A", "B", "C");
List<String> filteredNames = new ArrayList<>();
for (String name : names) {
if (name.startsWith("A")) {
filteredNames.add(name);
}
}
for (String name : filteredNames) {
System.out.println(name);
}
2. 현재 (Java 8 이상)
List<String> names = Arrays.asList("A", "B", "C");
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);
4. 시간 API 제공
과거에는 java.util.Date와 java.util.Calendar를 사용했지만, 이는 사용하기 불편했어요.
지금은 다들 쉽게 접근하는 java.time이 도입되었답니다.
💫 "이름을 읽는 경우"
1. 과거 (람다식 미 지원 버전)
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
System.out.println(formatter.format(date));
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, 1);
System.out.println(formatter.format(calendar.getTime()));
2. 현재 (Java 8 이상)
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
System.out.println("오늘: " + today);
System.out.println("내일: " + tomorrow);
하지만 종종, 지금도 Calender를 사용해야 할 때가 분명 있습니다.
저도 회사에서 쓰고 있거든요!
JAVA 11
JAVA 11은 2018년 9월에 오픈되었습니다. 그리고..
현대적인, 간결한 JAVA로 불립니다.
Java 8보다 안정적인 LTS 버전이라 많은 곳에서 채택하고 사용하고 있어요.
패치 내용도 간결화, 최적화 내용이 많답니다!
1. Var 타입 지원
Js에서 var, let 등을 사용하고, Python에서는 형식을 쓰지도 않습니다.
이처럼 Java에서도 "형식 자동 추론"을 지원하는 "VAR"이 추가되었습니다!
String message = "Hello, Java 11!";
System.out.println(message);
에서
var message = "Hello, Java 11!";
System.out.println(message);
이렇게!
2. HTTP/2 지원
API의 병렬 요청과 헤더 압축을 통한 네트워크 최적화 내용이에요.
우선순위를 정할 수 없고, 멀티플렉싱을 지원하지 않아 마치 싱글 스레드처럼 동작하던 HTTP/1.1에서
웹 성능과 최적화에 엄청난 강점을 가진 버전을 JAVA 11부터 지원합니다.
하지만, 2025년 지금은 HTTP/3까지 나왔어요! :D
3. 새로운 Garbage Collector
"ZGC"가 등장합니다.
<내용 추가 필요>
JAVA 17
JAVA 17은 2021년 9월에 오픈되었습니다. 그리고..
더 안전하고, 강력합니다.
Spring Boot 3.x와 기본적으로 호환되는 첫 LTS 버전입니다.
1. Switch 패턴 매칭 지원
정말.. 정말 개발자로서 환희를 지었던 기능입니다.
코드가 간결해지고, 유지보수하기 편해졌어요.
사실, 그냥 조건 분기를 더 간결하게 쓸 수 있게 되었습니다.
int day = 5;
String dayType;
switch (day) {
case 1: case 7:
dayType = "Weekend";
break;
default:
dayType = "Weekday";
break;
}
System.out.println(dayType);
이랬던 코드를,
int day = 5;
String dayType = switch (day) {
case 1, 7 -> "Weekend";
default -> "Weekday";
};
System.out.println(dayType);
이렇게 바꿔줍니다.
2. 새로운 GC의 등장!
SGC가 등장하고, 기존의 ZGC가 강화됐어요!
3. 난수 생성 최적화
난수 생성기를 대체할 새로운 API가 도입되었어요!
기존에는 Random을 사용했었는데, 지금은 RandomGenerator를 통해 유니크한 값을 뽑아낼 수 있습니다!
이전
Random random = new Random();
System.out.println(random.nextInt(100));
현재
RandomGenerator generator = RandomGenerator.of("Xoshiro256PlusPlus");
System.out.println(generator.nextInt(100));
JAVA 21
JAVA 21은 2023년 9월에 오픈되었습니다. 그리고..
현존 가장 최신 LTS입니다.
사실 이 단계는 저도 많이 안 써봤어요.
1. 가상 스레드 지원
가상 스레드는 기존의 플랫폼 스레드보다 가볍고 효율적으로 설계되었습니다.
우아한 형제들에서 관련된 내용을 자세하게 다루고 있으니,
한번 확인해 보세요!
https://techblog.woowahan.com/15398/
Java의 미래, Virtual Thread | 우아한형제들 기술블로그
JDK21에 공식 feature로 추가된 Virtual Thread에 대해 알아보고, Thread, Reactive Programming, Kotlin coroutines와 비교해봅니다.
techblog.woowahan.com
2. 멀티 플랫폼 지원 (ARM, Mac)
근 몇 년간 ARM 기반 프로세서가 많이 발전했죠.
클라우드 환경이 발전하면서 더더욱 각광받고 있습니다.
이에, 아래 두 가지 개선 사항이 생겼어요.
- ARM 아키텍처에 최적화된 JVM
- 기존 JVM이 x86 환경에 최적화되어 있었다면, ARM 프로세서를 위한 성능 개선 작업이 이루어졌습니다.
- 결과적으로 ARM 환경에서의 애플리케이션 실행 속도가 빨라지고, 더 적은 리소스를 소모하게 되었습니다.
- Apple Silicon 지원 강화
- Apple M1/M2 칩 기반 Mac에서 JAVA 애플리케이션의 실행 성능이 더욱 향상되었습니다.
- MacBook과 같은 개발 장비에서 더 부드럽고 효율적인 개발 환경을 제공합니다.
3. GC 튜닝 기능 추가
가비지 컬렉터(GC)의 성능을 더 세밀하게 관리할 수 있는 기능을 추가했습니다.
GC(Garbage Collector)는 JVM이 사용하지 않는 객체를 자동으로 제거해 메모리를 확보하는 역할을 합니다.
이 과정은 자바 애플리케이션의 성능과 안정성에 큰 영향을 미치고 있죠.
이에 Java21은
- GC 튜닝 기능 강화
- 개발자가 더 세밀하게 GC를 제어하고 튜닝할 수 있는 옵션들이 추가되었습니다.
- 이를 통해 메모리 사용량과 애플리케이션 성능을 최적화할 수 있습니다.
- 더 빠른 GC 작업 (저지연)
- GC가 메모리를 청소하는 동안 애플리케이션이 멈추는 시간을 줄였습니다(저지연 GC).
- 결과적으로 실시간 데이터 처리나 사용자 경험이 중요한 애플리케이션에서 더 부드럽게 동작합니다.
- ZGC(Zero Garbage Collector)와 G1GC 최적화
- 두 GC가 더욱 효율적으로 동작하도록 개선되었습니다.
이러한 개선을 통해
- 대규모 데이터 애플리케이션(예: 실시간 로그 분석)에서 메모리 사용량을 줄이고, 처리 속도를 높일 수 있습니다.
- 게임, 금융, AI와 같이 실시간 성능이 중요한 애플리케이션에서 지연 시간을 최소화합니다.
- 클라우드 환경에서 메모리 리소스를 효율적으로 관리하여 비용을 절감할 수 있습니다.
정리하자면...
왜 LTS를 사용하는가?
- 장기적인 안정성과 신뢰성이 필요.
- 기업 환경에서의 표준화와 지원 보장.
어떤 버전을 선택할까?
- 레거시 유지보수 : Java 8.
- 안정적이고 현대적인 개발 : Java 11.
- 새로운 기능과 성능 최적화 : Java 17.
- 최신 기술과 미래 대비 : Java 21.
마치며
확실히 어렵네요.
버전 별 특징을 알아본다는 것,
그리고 각 특징에 대해 상세하게 알아보려면 직접 개발을 해 봐야 알겠죠.
ZGC, SGC도 제대로 모르니, 이걸 가지고 또 포스팅할 수 있겠네요 :D
그럼 다들, 파이팅입니다!💫