Switch Expressions (Preview)
Java 12에서 가장 주목받은 기능은 Switch 표현식(JEP 325)입니다. 기존 switch 문은 break를 빠뜨리면 fall-through가 발생하는 고질적인 문제가 있었습니다. 새로운 화살표(→) 문법은 이 문제를 근본적으로 해결합니다.
자동 판매기를 떠올리면 이해가 쉽습니다. 기존 switch는 버튼을 누르면 모든 음료가 줄줄이 나오는 고장 난 판매기였다면, 새로운 switch는 선택한 음료만 정확히 나오는 정상 판매기입니다.
public class SwitchExpressionDemo {
public static void main(String[] args) {
// === 기존 switch 문: break 누락 시 fall-through 위험 ===
String day = "MONDAY";
int numLettersOld;
switch (day) {
case "MONDAY":
case "FRIDAY":
case "SUNDAY":
numLettersOld = 6;
break;
case "TUESDAY":
numLettersOld = 7;
break;
default:
numLettersOld = -1;
}
// === 새로운 switch 표현식: 화살표 문법, 값 반환 ===
int numLettersNew = switch (day) {
case "MONDAY", "FRIDAY", "SUNDAY" -> 6; // 쉼표로 다중 케이스
case "TUESDAY" -> 7;
case "WEDNESDAY", "THURSDAY" -> 8;
case "SATURDAY" -> 8;
default -> -1;
};
System.out.println("기존 방식: " + numLettersOld);
System.out.println("새로운 방식: " + numLettersNew);
// 출력:
// 기존 방식: 6
// 새로운 방식: 6
}
}
화살표 문법의 장점은 세 가지입니다. 첫째, break가 필요 없어 fall-through 버그가 원천 차단됩니다. 둘째, 하나의 case에 여러 값을 쉼표로 나열할 수 있습니다. 셋째, switch 자체가 값을 반환하는 **표현식(expression)**이 됩니다.
참고로 Java 12에서는 프리뷰 기능이므로 컴파일 시 --enable-preview 플래그가 필요합니다.
javac --enable-preview --source 12 SwitchExpressionDemo.java
java --enable-preview SwitchExpressionDemo
Shenandoah GC — 저지연 GC의 새로운 선택지
Shenandoah GC(JEP 189)는 Red Hat이 주도한 저지연(Low-Latency) 가비지 컬렉터입니다. 힙 크기와 관계없이 **일관된 짧은 GC 중단 시간(pause time)**을 목표로 합니다.
고속도로 공사에 비유하면, 기존 GC가 차선을 전면 통제하고 공사하는 방식이라면, Shenandoah는 차량이 달리는 중에 옆에서 동시에 공사하는 방식입니다.
| GC | 중단 시간 특성 | 힙 크기 영향 |
|---|---|---|
| G1 (기본) | 수십ms ~ 수백ms | 힙 커지면 증가 |
| Shenandoah | 10ms 미만 목표 | 힙 크기와 무관 |
| ZGC | 10ms 미만 목표 | 힙 크기와 무관 |
Shenandoah를 활성화하려면 JVM 옵션을 추가합니다.
java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -jar your-app.jar
G1 GC 개선
Java 12에서는 기본 GC인 G1에도 두 가지 중요한 개선이 적용되었습니다.
즉시 반환 미사용 커밋 메모리(JEP 346): G1이 유휴 시간에 Java 힙 메모리를 OS에 반환합니다. 컨테이너 환경에서 메모리 절약 효과가 큽니다.
Abortable Mixed Collections(JEP 344): Mixed GC가 목표 중단 시간을 초과하면 중간에 중단할 수 있습니다. GC 중단 시간 예측 가능성이 높아졌습니다.
Compact Number Formatting
CompactNumberFormat은 1,000을 “1K”, 1,000,000을 “1M”처럼 간결하게 표시합니다. 대시보드나 통계 화면에서 유용합니다.
import java.text.NumberFormat;
import java.util.Locale;
public class CompactNumberDemo {
public static void main(String[] args) {
// 한국어 로케일 — 짧은 형식
NumberFormat shortKo = NumberFormat.getCompactNumberInstance(
Locale.KOREA, NumberFormat.Style.SHORT
);
System.out.println("1,000 → " + shortKo.format(1000));
System.out.println("1,000,000 → " + shortKo.format(1_000_000));
System.out.println("1,000,000,000 → " + shortKo.format(1_000_000_000));
// 영어 로케일 — 긴 형식
NumberFormat longEn = NumberFormat.getCompactNumberInstance(
Locale.US, NumberFormat.Style.LONG
);
System.out.println("2500 (EN LONG) → " + longEn.format(2500));
// 소수점 자릿수 설정
shortKo.setMaximumFractionDigits(1);
System.out.println("15,750 → " + shortKo.format(15_750));
// 출력:
// 1,000 → 1천
// 1,000,000 → 100만
// 1,000,000,000 → 10억
// 2500 (EN LONG) → 3 thousand
// 15,750 → 1.6만
}
}
String 신규 메서드 — indent()와 transform()
Java 12에서 String 클래스에 두 가지 편의 메서드가 추가되었습니다.
public class StringMethodsDemo {
public static void main(String[] args) {
// === indent(n): 각 줄 앞에 n칸 공백 추가 (음수면 제거) ===
String text = "첫째 줄\n둘째 줄\n셋째 줄";
String indented = text.indent(4);
System.out.println("들여쓰기 적용:");
System.out.println(indented);
// 출력:
// 첫째 줄
// 둘째 줄
// 셋째 줄
// === transform(): 문자열에 함수 적용 후 결과 반환 ===
String result = "hello, java 12"
.transform(String::toUpperCase)
.transform(s -> s.replace(" ", "_"))
.transform(s -> "[ " + s + " ]");
System.out.println(result);
// 출력: [ HELLO,_JAVA_12 ]
// transform은 메서드 체이닝에 유용합니다
// 기존에는 중간 변수가 필요했던 변환을 파이프라인처럼 연결할 수 있습니다
int length = "Java 12 features"
.transform(String::trim)
.transform(String::length);
System.out.println("문자열 길이: " + length);
// 출력: 문자열 길이: 16
}
}
transform()은 함수형 파이프라인 패턴을 String에 적용한 것입니다. 중간 변수 없이 변환을 체이닝할 수 있어 가독성이 좋아집니다.
JMH 기본 포함
Java 12부터 **JMH(Java Microbenchmark Harness)**가 JDK 소스 트리에 포함됩니다(JEP 230). JMH는 JVM 워밍업, JIT 컴파일, 데드 코드 제거 등의 함정을 피해 정확한 마이크로벤치마크를 작성할 수 있게 해주는 도구입니다.
이전에는 별도로 JMH 의존성을 추가해야 했지만, JDK 12부터는 JDK 자체 코드의 성능 회귀를 쉽게 추적할 수 있도록 기본 포함되었습니다.
정리
| 기능 | 상태 | 핵심 포인트 |
|---|---|---|
| Switch Expressions | Preview | 화살표 문법, 값 반환, fall-through 차단 |
| Shenandoah GC | 실험적 | 힙 크기 무관 저지연 GC |
| G1 GC 개선 | 정식 | 미사용 메모리 OS 반환, Abortable Mixed GC |
| CompactNumberFormat | 정식 | 1000 → “1천” 간결한 숫자 포맷 |
| String.indent() | 정식 | 줄 단위 들여쓰기 추가/제거 |
| String.transform() | 정식 | 함수형 파이프라인 체이닝 |
| JMH 포함 | 정식 | JDK 소스에 벤치마크 프레임워크 내장 |
Java 12는 switch 문법 현대화의 시작점이자, JVM 성능 튜닝의 선택지를 넓힌 릴리스입니다. Switch Expressions는 이후 Java 14에서 정식 확정되며, Shenandoah GC는 Java 15에서 프로덕션 레디로 승격됩니다. 프리뷰 기능이라고 무시하지 말고 미리 익혀두면 버전 업그레이드 시 자연스럽게 적용할 수 있습니다.