Java 18 (2022)
1) UTF-8 기본 문자셋(기본값 통일)
- 운영체제/로케일에 관계 없이 기본 인코딩이 UTF-8.
System.out.println(Charset.defaultCharset());
해설: 레거시 환경에서 발생하던 인코딩 혼선을 낮춰줍니다.
2) Simple Web Server (jwebserver)
- 정적 파일을 서빙하는 초경량 개발용 웹 서버.
# 현재 디렉토리를 8000번 포트로 서빙
jwebserver --directory . --port 8000
해설: 문서/샘플 테스트에 유용. 보안/프락시 등은 최소한.
3) JavaDoc @snippet
- 코드 조각을 문서에 삽입.
public class SnippetExample {}
해설: JavaDoc 내 코드 유지/검증이 쉬워집니다.
4) Vector API / FFM API(진행형, Incubator/Preview)
var sp = FloatVector.SPECIES_PREFERRED;
var a = FloatVector.broadcast(sp, 2.0f);
var b = FloatVector.broadcast(sp, 4.0f);
var c = a.mul(b);
System.out.println(c);
해설: 수치 연산을 SIMD로 가속. (실사용 시 --add-modules 설정 필요)
Java 19 (2022)
1) Virtual Threads (Preview, Project Loom)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<Callable<String>> tasks = IntStream.range(0, 5)
.mapToObj(i -> (Callable<String>) () -> "task-" + i)
.toList();
var results = executor.invokeAll(tasks);
for (var r : results) System.out.println(r.get());
}
해설: 경량 스레드로 동시성 코드를 단순화. 블로킹 I/O도 저렴해집니다.
2) Record Patterns (Preview)
record Point(int x, int y) {}
static String locate(Object obj) {
return switch (obj) {
case Point(int x, int y) when x == 0 && y == 0 -> "origin";
case Point(int x, int y) -> "point(" + x + "," + y + ")";
default -> "unknown";
};
}
해설: record를 패턴으로 분해 매칭해 값 추출을 간결하게.
3) Pattern Matching for switch (더 성숙한 Preview)
static String toStr(Object o) {
return switch (o) {
case String s when s.isEmpty() -> "<empty>";
case String s -> "S:" + s;
case Integer i && i > 0 -> "positive int";
default -> "other";
};
}
4) Structured Concurrency (Incubator)
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var f1 = scope.fork(() -> callServiceA());
var f2 = scope.fork(() -> callServiceB());
scope.join().throwIfFailed();
return combine(f1.result(), f2.result());
}
해설: 관련 작업을 묶어 수명/에러/취소를 한 덩어리로 관리.
Java 20 (2023)
1) Scoped Values (Incubator)
static final ScopedValue<String> USER = ScopedValue.newInstance();
ScopedValue.where(USER, "kim").run(() -> {
System.out.println("user = " + USER.get());
});
해설: 불변 컨텍스트를 호출 트리에 안전하게 전달.
2) Record Patterns (2nd Preview) / switch 패턴(4th Preview)
record Box<T>(T value) {}
static String unbox(Object o) {
return switch (o) {
case Box(String s) -> s;
case Box(Integer i) -> "int=" + i;
default -> "unknown";
};
}
3) FFM API / Virtual Threads / Structured Concurrency의 재프리뷰
- API 안정화 진행. 사용하는 JDK 버전에 맞춰 패키지·옵션 확인 필요.
Java 21 (2023, LTS)
1) Virtual Threads 정식
Thread.ofVirtual().start(() -> System.out.println("hello vt")).join();
해설: 비동기 I/O를 쓰지 않아도 간단한 동시성 구현 가능.
2) Record Patterns 정식 + Pattern Matching for switch 정식
record Range(int start, int end) {}
static int length(Object o) {
return switch (o) {
case Range(int s, int e) when s <= e -> e - s;
case String s -> s.length();
default -> 0;
};
}
3) Sequenced Collections
SequencedCollection<String> sc = new ArrayList<>();
sc.addFirst("a"); sc.addLast("b");
System.out.println(sc.getFirst());
System.out.println(sc.getLast());
해설: 앞/뒤 모두에서 다루기 쉬운 양방향 순서 컬렉션.
4) String Templates (Preview)
String name = "Kim";
int n = 3;
String msg = STR."Hello, {name}! n={n}";
System.out.println(msg);
해설: 템플릿 처리기를 통해 문자열·검증·포맷을 선언적으로.
Java 22 (2024)
1) String Templates (2nd Preview)
String who = "world";
String s = STR."Hi, {who}";
해설: 템플릿 안전성/가독성 개선 테스트 계속.
2) Stream Gatherers (Preview)
var runningSums = Stream.of(1,2,3,4,5)
.gather(Gatherers.scan(0, Integer::sum))
.toList();
System.out.println(runningSums);
해설: Gatherers.*로 스트림 수집/변환을 강력하게 확장.
3) Scoped Values (2nd Incubator) / Vector/FFM/Structured Concurrency 재진전
- API 다듬기 지속.
Java 23 (2024)
1) Stream Gatherers (2nd Preview)
var windows = Stream.of(1,2,3,4,5,6)
.gather(Gatherers.windowFixed(3))
.toList();
System.out.println(windows);
2) String Templates (Preview 기능이 제거됨)
- 템플릿 실험은 중단/보류. (향후 재도입 가능성은 별개 이슈)
3) FFM/Vector/Scoped Values 등 재프리뷰/인큐베이터
- 이식성/안전성/성능을 위한 세부 다듬기.
Java 24 (2025)
1) Stream Gatherers 정식
var folded = Stream.of("a","b","c")
.gather(Gatherers.fold(
new StringBuilder(),
(sb, s) -> sb.append(s.toUpperCase()),
StringBuilder::append))
.map(StringBuilder::toString)
.toList();
System.out.println(folded);
해설: 스트림 파이프라인에서 고급 수집/변환을 표준화.
2) 패턴 매칭 확장(원시 타입 포함)
static String inspect(Object o) {
return switch (o) {
case int i -> "int:" + i;
case long l -> "long:" + l;
case double d -> "double:" + d;
case String s && s.isBlank() -> "<blank>";
default -> "other";
};
}
해설: Object에 박싱돼 넘어온 값도 언박싱+패턴으로 간결 처리.
3) Compact Object Headers (Incubator, Project Lilliput)
- 객체 헤더 축소로 힙 효율 향상. (JVM 옵션 필요, 실험적)
4) Generational Shenandoah GC (Experimental)
# 개념: 실험적 GC 활성화 예시(옵션은 빌드/배포판에 따라 상이)
java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational ...
해설: 젠네레이션 기반으로 페이즈/일시중지 개선 목표.
5) 보안/플랫폼/언어 생태 관련 변화
- Key Derivation Function API 추가(보안 키 파생 표준화).
- Module Import Declarations(실험/미리보기 성격): 모듈 선언 편의.
- Simple Source Files & Instance main 개선: 더 간단한 엔트리 작성.
- sun.misc.Unsafe 경고 강화, Windows 32-bit 포트 제거.
실무 Tips (18~24 묶음)
- 동시성: 대규모 I/O → Virtual Threads 우선 검토. 태스크 묶음 관리는 Structured Concurrency.
- 컨텍스트 전달: ThreadLocal 대신 Scoped Values(Incubator) 고려(불변·안전).
- 문자열/템플릿: String Templates는 21~22에서만 Preview. 23에서 제거되었으니 버전별 분기 필요.
- 고성능 수치/스트림: Vector API(하드웨어 의존), Stream Gatherers(24 정식)로 파이프라인 강화.
- 네이티브 연동: FFM API는 버전별 패키지/네이밍 변화를 따라가며 마이그레이션.
- JVM 옵션: Incubator/Experimental 기능은 모듈 추가/옵션 활성화가 필요할 수 있음.
댓글