⚡ java 21 LTS 릴리즈 버전
java 21 릴리즈가 2023년 9월 19일 어제 날짜로 공개가 되었다. 😁
해당 버전이 나오기 전부터 java 21 버전은 java의 혁신이라고 많이 얘기를 했고, 많은 기대를 받고 있는 버전중에 하나이다. 추가된 주요 기능을 하나씩 파악을 하고 있으며 추가된 기능에 대해서 정리를 해보려고 한다.
⚡ 주요 기능
주요 기능에 대해서 자세하게 설명은 힘들거 같다(...) 주요 기능에 대해서 개인적으로 정리 하면서 읽어보고 있지만 중요한 내용이 너무 많이 있다. 추가적은 내용은 링크를 타고 들어가서 어떤 의도로 개발을 했으면 어떤 내용이 변경되 었는지 한번 더 확인 해보면 좋을거 같다. :)
👍 가상 스레드
( JEP 444 )
가상 스레드는 OS가 아닌 JDK에서 제공하는 스레드의 경량 구현 이다.
다른 다중 스레드 언어 (go, Erlang)에서 성공한 사용자 모드 스레드의 한 형태라고 한다.
가상 스레드는 M:N 스케줄링을 사용한다. 즉, 많은 수(M)의 가상 스레드가 더 적은 수(N)의 OS 스레드에서 실행되도록 예약 된다.
공식 페이지에서 예시를 가져왔다.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
}
이 예의 작업은 간단한 코드(1초 동안 절전 모드)이며 최신 하드웨어는 이러한 코드를 동시에 실행하는 10,000개의 가상 스레드를 쉽게 지원할 수 있다. 그 이면에서 JDK는 소수의 OS 스레드(아마도 한 개 정도)에서 코드를 실행한다.
위처럼 코드를 작성했을때, 시스템 및 운영체에 따라서 프로그램이 충동할수도 있지만 어떻게 순차적으로 처리되는지에 대한 내용도 정리가 되어있다. (내부 코드를 한번 봐야할듯 싶다)
또한 어떤 경우에 처리량을 크게 향상 시킬수 있는지, 스레드를 덤프 예시, 메모리 사용 및 가비지 컬렉션 수집 등 다양한 내용이 정리 되어 있다.
👍 외부 함수 및 메모리 API
( JEP 442 )
java 프로그램이 Java 런타임 외부의 코드 및 데이터와 상호 운용할 수 있는 API를 도입한다. 외부 기능(즉, JVM 외부 코드)을 효율적으로 호출하고 외부 메모리(즉, JVM에서 관리하지 않는 메모리)에 안전하게 액세스함으로써 API를 사용하면 Java 프로그램이 취약성과 위험 없이 기본 라이브러리를 호출하고 기본 데이터를 처리할 수 있다.
JNI (Java Native Interface )를 우수한 순수 Java 개발 모델로 대체를 목표로 하고 있으며, 외부 메모리에 작동하는 방법을 제공하고, 추가적으로 다른 플랫폼 (32 비트) 및 다른 언어로 작성된 외부 기능을 수용하는 방법을 제공 한다고 한다. (C 뿐만 아니라 C++, Fortarn)
👍 Sequenced Collections
( JEP 431 )
정의된 순서로 컬렉션을 나타내는 새로운 인터페이스를 도입했다.
interface SequencedCollection<E> extends Collection<E> {
// new method
SequencedCollection<E> reversed();
// methods promoted from Deque
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}
순차화된 컬렉션에는 첫 번째 요소와 마지막 요소가 있으며, 그 사이의 요소에는 후속 요소와 선행 요소가 있다.
순차 컬렉션은 양쪽 끝에서 공통 작업을 지원하며 처음부터 마지막으로, 마지막에서 처음으로(즉, 정방향 및 역방향) 요소 처리를 지원 한다.
세부적으로는 기존 클래스와 인터페이스를 개선하기 위해 다음과 같은 조정을 수행 했다.
👍 Record Patterns
( JEP 440 )
패턴 일치를 확장하여 정교한 데이터를 조회 하고, 중첩 패턴을 추가하여 더 많은 구성을 가능하게 한다.
// As of Java 16
record Point(int x, int y) {}
static void printSum(Object obj) {
if (obj instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x+y);
}
}
// As of Java 21
static void printSum(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x+y);
}
}
여기서 Point(int x, int y) 는 레코드 패턴이다. 추출된 구성 요소에 대한 지역 변수 선언을 패턴 자체로 끌어 올리고, 값이 패턴과 일치할 때 접근자 메서드를 호출하여 해당 변수를 초기화 한다.
👍 Pattern Matching for switch
( JEP 441 )
자주 사용하는 switch 문도 향상된 기능이 존재한다. 공식 페이지에서 제공한 향상된 기능에 대해서 설명하려고 한다.
(아래의 예시를 통해서 추가적으로 내용을 정리 하도록 한다.)
NULL 허용
이전 버전과 의 호환성을 위해서 null 케이스와 default 는 일치 하지 않는다.!!
// As of Java 21
static void testFooBarNew(String s) {
switch (s) {
case null -> System.out.println("Oops");
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
}
선택적 when절 추가
기존 코드를 생각해보면 case 안에서 예외처리가 필요한 경우, if-else 구문을 통해서 처리를 했어야 했다. 이에 대한 개선 방법으로 아래와 같은 방법을 제시 했다.
// As of Java 21
static void testStringNew(String response) {
switch (response) {
case null -> { }
case String s
when s.equalsIgnoreCase("YES") -> {
System.out.println("You got it");
}
case String s
when s.equalsIgnoreCase("NO") -> {
System.out.println("Shame");
}
case String s -> {
System.out.println("Sorry?");
}
}
}
enum 사용 추가
현재 열거형 상수를 사용은 case 문에서 매우 제한적이다. 간단한 이름인 경우에야 쉽게 사용 가능 하지만 패턴 레이블을 추가한 후에도 제약 조건이 있어서 불필요하게 장황한 코드가 생성 되었다.
// As of Java 21
sealed interface CardClassification permits Suit, Tarot {}
public enum Suit implements CardClassification { CLUBS, DIAMONDS, HEARTS, SPADES }
final class Tarot implements CardClassification {}
static void exhaustiveSwitchWithoutEnumSupport(CardClassification c) {
switch (c) {
case Suit s when s == Suit.CLUBS -> {
System.out.println("It's clubs");
}
case Suit s when s == Suit.DIAMONDS -> {
System.out.println("It's diamonds");
}
case Suit s when s == Suit.HEARTS -> {
System.out.println("It's hearts");
}
case Suit s -> {
System.out.println("It's spades");
}
case Tarot t -> {
System.out.println("It's a tarot");
}
}
}
향상된 열거형 상수 사용 방법
// As of Java 21
sealed interface Currency permits Coin {}
enum Coin implements Currency { HEADS, TAILS }
static void goodEnumSwitch1(Currency c) {
switch (c) {
case Coin.HEADS -> { // Qualified name of enum constant as a label
System.out.println("Heads");
}
case Coin.TAILS -> {
System.out.println("Tails");
}
}
}
static void goodEnumSwitch2(Coin c) {
switch (c) {
case HEADS -> {
System.out.println("Heads");
}
case Coin.TAILS -> { // Unnecessary qualification but allowed
System.out.println("Tails");
}
}
}
허용되지 않는 경우 예시
// As of Java 21
static void badEnumSwitch(Currency c) {
switch (c) {
case Coin.HEADS -> {
System.out.println("Heads");
}
case TAILS -> { // Error - TAILS must be qualified
System.out.println("Tails");
}
default -> {
System.out.println("Some currency");
}
}
}
위의 내용 외에도 향상된 내용에 대해서도 설명이 되어 있다. :)
👍 추가적으로 향상된 내용
위에서 설명한 내용 이외에도 향상된 내용이 릴리즈 노트에 적혀 있다. 중요한 내용이 너무 많지만 내용을 정리 하려면 많은 시간이 필요해서 따로 향상된 부분에 대해서 정리 해놓으려고 한다.
- 가비지 컬렉터 (ZGC) 가 확장됨에 따라 애플리케이션의 성능이 향상 되었다 ( JEP439 )
- 공개 키 암호화를 사용하여 대칭 키를 보호하기 위한 암호화 기술인 키 캡슐화 메커니즘(KEM)용 API를 소개 ( JEP452 )
이외에 프리뷰인 내용도 있지만 여기서는 설명하지 않도록 하겠다.
⚡ TMI
java 21에서는 수정된 것으로 표시된 JIRA 문제 2,585개 중 Oracle이 1,868개 를 완료했고, 717개는 Java 커뮤니티의 다른 구성원이 기여했습니다. 오라클은 Amazon, ARM, Azul, Google, Huawei, IBM, Intel, ISCAS, Red Hat, Rivos, SAP 및 Tencent를 포함한 조직에서 일하는 개발자들의 주목할만한 기여에 감사드립니다. 또한 Bellsoft, Loongson과 같은 소규모 조직과 Java 21 수정 사항의 8%를 공동으로 기여한 독립 개발자의 기여를 확인하는 데 감사드립니다.
⚡ 생각
java 21가 나오면서 java 진영에 큰 변화가 생길거라고 생각하고 있다. 실제 도입까지는 분명 많은 시간이 걸리긴 하겠지만 이전 17 버전 보다 21 버전을 사용했을때 대용량 데이터 처리 및 비동기 처리 쪽에서는 분명한 강점이 있고, 향상된 기능들이 많기 때문에 충분히 내용을 인지하고 테스트를 한 이후에 내부에 반영하는 부분에 대해서 검토를 해보려고 한다.
앞으로 많은 라이브러리 및 드라이버에서 자바 최신 버전을 지원해서 더 좋은 퍼포먼스가 나오길 기대하고 있고 내용을 찾아 보고 있다.
⚡ 참조 사이트 (링크)
'Java' 카테고리의 다른 글
[JAVA] Connection leck 관련 Apparent connection leak detected 경고 관련 내용 (0) | 2023.12.29 |
---|---|
[Pythod] 파이썬 개발 도전 (2) (0) | 2023.12.10 |
[JAVA] stream forEach 에 관한 내용 정리 (0) | 2023.09.16 |
[JAVA] String isEmpty 및 isBlank 사용 정리 (0) | 2023.07.29 |
[JPA] 하이버네이트(Hibernate) 에 대한 내용 정리 (0) | 2023.05.01 |