IT/Java

Java21 스펙 빠르게 훑어보기 (feat. 2023-09-19)

yeTi 2023. 9. 20. 08:41

안녕하세요. yeTi입니다.

오늘은 어제(2023-09-19) 공식적으로 발표한 Java21의 스펙을 간략하게 살펴보고자 합니다.

개요

  • Core Java Library
    • JEP 431: Sequenced Collections
    • JEP 442: Foreign Function & Memory API (Third Preview)
    • JEP 444: Virtual Threads
    • JEP 446: Scoped Values (Preview)
    • JEP 448: Vector API (Sixth Incubator)
    • JEP 453: Structured Concurrency (Preview)
  • Java Language Specification
    • JEP 430: String Templates (Preview)
    • JEP 440: Record Patterns
    • JEP 441: Pattern Matching for switch
    • JEP 443: Unnamed Patterns and Variables (Preview)
    • JEP 445: Unnamed Classes and Instance Main Methods (Preview)
  • HotSpot
    • JEP 439: Generational ZGC
    • JEP 449: Deprecate the Windows 32-bit x86 Port for Removal
    • JEP 451: Prepare to Disallow the Dynamic Loading of Agents
  • Security Library
    • JEP 452: Key Encapsulation Mechanism API

Core Java Library

JEP 431: Sequenced Collections

SequencedCollection 을 추가하여 처음과 마지막 순서의 원소를 조회할 수 있는 컬렉션을 표현하는 새로운 인터페이스를 도입했습니다.

이는 구현체에 속해 일관성없이 제공하던 인터페이스를 일관되게 제공할 수 있도록 해줍니다.

관련 인터페이스 : SequencedSet, SequencedMap, Collections

JEP 444: Virtual Threads

가상 쓰레드는 처리량이 많은 동시성 애플리케이션을 개발하고 모니터링하고 유지 및 관리하는데 드는 비용을 획기적으로 줄여줄 경량 쓰레드입니다.

Java21 부터는 이를 JVM 레벨에서 처리하도록 하여 코틀린의 코루틴과 다르게 키워드를 명시해주지 않아도 JVM이 알아서 논블로킹 처리를 해주기 때문에 많은 이점을 가질 수 있다.

Java Language Specification

JEP 440: Record Patterns

레코드(Record)에 타입 패턴을 함께 적용하여 레코드의 값을 손쉽게 처리할 수 있도록 도와줍니다.

AS-IS

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);
  }
}

TO-BE

static void printSum(Object obj) {
  if (obj instanceof Point(int x, int y)) {
    System.out.println(x+y);
  }
}

이러한 움직임은 자바 언어가 보다 데이터 중심적인 프로그래밍 스타일로 나아가기 위함입니다.

JEP 441: Pattern Matching for switch

패턴 매칭을 스위치 문까지 확장시켰습니다.

AS-IS

static String formatter(Object obj) {
  String formatted = "unknown";
  if (obj instanceof Integer i) {
    formatted = String.format("int %d", i);
  } else if (obj instanceof Long l) {
    formatted = String.format("long %d", l);
  } else if (obj instanceof Double d) {
    formatted = String.format("double %f", d);
  } else if (obj instanceof String s) {
    formatted = String.format("String %s", s);
  }
  return formatted;
}

TO-BE

static String formatterPatternSwitch(Object obj) {
  return switch (obj) {
    case Integer i -> String.format("int %d", i);
    case Long l -> String.format("long %d", l);
    case Double d -> String.format("double %f", d);
    case String s -> String.format("String %s", s);
    default -> obj.toString();
  };
}

추가적으로 null에 해당하는 케이스를 스위치 내부에서 검사할 수 있게 되었고, case 문의 분기에 대해 when 구문을 제공하여 보다 간결하게 처리할 수 있도록 개선되었다.

Enum 에 대한 switch 문도 개선되었다.

TO-BE

static void exhaustiveSwitchWithBetterEnumSupport(CardClassification c) {
  switch (c) {
    case Suit.CLUBS -> {System.out.println("It's clubs");}
    case Suit.DIAMONDS -> {System.out.println("It's diamonds");}
    case Suit.HEARTS -> {System.out.println("It's hearts");}
    case Suit.SPADES -> {System.out.println("It's spades");}
    case Tarot t -> {System.out.println("It's a tarot");}
  }
}

HotSpot

JEP 439: Generational ZGC

ZGC는 짧은 지연 시간과 높은 확정성을 위해 고안된 GC 알고리즘으로 Java 15부터 프로덕션 환경에서 사용할 수 있게 되었는데 이번 21 버전에서는 성능이 개선되었습니다.

JEP 449: Deprecate the Windows 32-bit x86 Port for Removal

Windows 32bit 용 빌드를 구성하려고 시도할 때 오류 메세지가 표시됩니다.

JEP 451: Prepare to Disallow the Dynamic Loading of Agents

자바 21에서는 실행 중인 JVM에 에이전트가 동적으로 로드될 때 경고를 발행시키도록 수정되었습니다. 물론 JVM 시작 시에 에이전트를 로드하는 것은 경고를 발생시키지 않습니다.

Security Library

JEP 452: Key Encapsulation Mechanism API

공개 키 암호화를 사용하여 대칭 키를 보호하는 암호화 기술인 KEM(Key Encapsulation Mechanism) API가 도입되었습니다.

양자 공격을 방어하기 위한 핵심 도구가 될 것이고, 이미 다른 보안 제공업체들은 이미 표준 KEM API에 대한 필요성을 표명했습니다.

자바 역시 이를 공식적으로 도입하기로 결정함에 따라 추가된 스펙입니다.

결론

전반적인 흐름은 데이터 중심적인 프로그래밍 스타일을 지원해나가면서 성능 개선을 위해 가상 쓰레드를 도입하고 GC 의 성능을 개선해나가는 것으로 보입니다.

그리고 보안측면에서도 양자 공격을 고려하고 있다는 점이 양자 컴퓨팅이라는 것이 막연한 미래의 일은 아니라는 자각을 일으켜줍니다.

보다 상세한 내용들은 차차 공유해보도록 하겠습니다.