JDK의 버전별 변경 사항은 이곳을 참고하세요.
Spec
Java SE 14 Platform JSR 389에 정의된 바와 같이 JSR 389 구현이 목표
실제 Spec은 Final Release Specification 문서를 참고해야 함
Final Release Specification Feature Summary
전체 JEP Feature 목록은 OpenJDK의 JDK 14 문서로 확인할 수 있다.
Component | Feature |
specification / language | Pattern Matching for instanceof (Preview) |
hotspot / runtime | Helpful NullPointerExceptions |
specification / language | Records (Preview) |
tools / javac | Switch Expressions (Standard) |
hotspot / gc | Remove the Concurrent Mark Sweep (CMS) Garbage Collector |
hotspot / gc | Deprecate the ParallelScavenge + SerialOld GC Combination |
specification / language | Text Blocks (Second Preview) |
JEP 305: Pattern Matching for instanceof (Preview)
Pattern Matching을 좀 더 편하게 사용할 수 있는 기능이 제공된다.
기존엔 instanceof를 다음처럼 사용하였다.
if (obj instanceof String) {
String s = (String) obj;
// use s
}
String 인 경우를 확인한 후 String으로 해당 값을 캐스팅하기 위한 과정이 필요했다.
다음과 같이 casting 후 변수 지정을 할 수 있게 된다.
if (obj instanceof String s) {
// can use s here
} else {
// can't use s here
}
이는 복잡한 조건식에도 적용이 가능하다.
if (obj instanceof String s && s.length() > 5) {.. s.contains(..) ..}
&& 연산자의 경우 s에 해당 값이 캐스팅되어 다음 조건 연산자에서 사용할 수 있고 블록 내에서도 사용할 수 있다.
하지만 아래처럼 || 연산인 경우 이후에 s가 생성되지 않기 때문에 사용할 수 없다.
if (obj instanceof String s || s.length() > 5) {.. s.contains(..) ..}
명시적인 캐스팅 수를 줄여준다.
@Override public boolean equals(Object o) {
return (o instanceof CaseInsensitiveString) &&
((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
위의 경우 아래처럼 줄일 수 있다.
@Override public boolean equals(Object o) {
return (o instanceof CaseInsensitiveString cis) &&
cis.s.equalsIgnoreCase(s);
}
JEP 358: Helpful NullPointerExceptions
NullPointerException에 대해 null 인 변수를 정확하게 설명하도록 수정되었다.
기존의 경우 아래 호출에 NullPointerException이 발생하면
a.i = 99;
아래처럼 발생한 파일 이름과 라인을 출력했다.
Exception in thread "main" java.lang.NullPointerException
at Prog.main(Prog.java:5)
에러가 발생한 위치를 알 수 있지만 아래처럼 중첩해서 변수를 호출한 경우 어느 변수에서 NPE가 발생한 것인지 알기 어려웠다.
a.b.c.i = 99;
비슷한 경우로 배열을 사용하는 경우나 객체의 값을 지정하는 경우도 있다.
a[i][j][k] = 99;
a.i = b.j;
이제 아래처럼 NPE에 대해 에러를 설명하도록 변경되었다.
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)
Exception in thread "main" java.lang.NullPointerException:
Cannot read field "c" because "a.b" is null
at Prog.main(Prog.java:5)
Exception in thread "main" java.lang.NullPointerException:
Cannot load from object array because "a[i][j]" is null
at Prog.main(Prog.java:5)
a.i = b.j에서 NPE가 발생한 경우는 다음과 같다.
Exception in thread "main" java.lang.NullPointerException:
Cannot read field "j" because "b" is null
at Prog.main(Prog.java:5)
JEP 359: Records (Preview)
14에 preview로 추가된 record 란 개념이 생겼다.
record는 단순한 불변 데이터를 선언하기 위한 간단한 문법을 제공한다.
java 개발을 하면 대부분 lombok을 사용해 필드의 getter, setter를 간단하게 구현하게 되지만 순수 java는 object를 생성하고 기본적인 getter/setter를 관리하는 것이 불편하다.
kotlin은 아예 필드를 public으로 사용하고 getter, setter를 사용하지 않는 형태의 data class를 사용하는 것을 제안하는데 record는 이와 유사하다.
record Point(int x, int y) { }
다만 record는 확장할 수 없고, final 필드만 선언할 수 있다.
또한 선언된 모든 다른 필드는 static 하다.
따라서 생성자를 통해 필드가 선언되어야 한다.
유효성 검증을 생성자에서 사용해야 한다. 생성자는 아래처럼 쓴다. (생성자 매개 변수가 생략됨)
record Range(int lo, int hi) {
public Range {
if (lo > hi) /* referring here to the implicit constructor parameters */
throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi));
}
}
개인 의견 : 개인적으로 좋아하지 않는 방향이지만 간단한 데이터 도메인을 만들어 사용하기 위한 방식을 java에서 제공하는 것이려니 생각한다. Kotllin처럼 nullsafe 개념으로 확장하고 decorator 패턴을 쓰는 방향으로 가려는 것인지도 모르겠다.
JEP 361: Switch Expressions (Standard)
앞으로 표현식이나 구문으로 Switch 구문을 사용할 수 있게 된다.
Switch 표현식은 JDK 12에서 이미 Preview로 공개되었고 JDK 13을 거처 14에서 표준으로 지정되었다.
자세한 내용은 이전 글을 참고하면 된다.
2019/07/18 - [Study/Java] - JDK 12 New Features
2019/09/25 - [Study/Java] - JDK 13 New Features
JEP 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector
G1 GC가 나온 이후 옵션으로 계속 사용 가능했던 CMS가 제거된다.
현재 G1과 ZGC, Shenandoah를 GC로 제공하고 있다.
또한 이번에 반영된 JEP 364, JEP 365를 통해 Window와 macOS에서 ZGC를 사용할 수 있도록 추가되었다. (둘 다 아직 Experimental이라 아래 옵션을 추가해서 사용한다.
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination
CMS와 마찬가지로 ParallelGC도 제거된다.
JEP 368: Text Blocks (Second Preview)
JDK 13에 추가되었던 Text Block의 두 번째 Preview.
자세한 내용은 이전 글을 참고하면 된다.
2019/09/25 - [Study/Java] - JDK 13 New Features
추가된 내용은 New escape sequences인데 \<line-terminator>를 사용한 경우 명시적으로 개행 문자의 삽입을 억제한다.
코딩할 땐 줄 바꿔서 처리해도 실제 실행 시엔 줄이 안 바뀌는 기능이다.
기존 사용은 아래와 같다.
String literal = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
"elit, sed do eiusmod tempor incididunt ut labore " +
"et dolore magna aliqua.";
이와 동일한 효과를 아래처럼 쓸 수 있게 된다.
String text = """
Lorem ipsum dolor sit amet, consectetur adipiscing \
elit, sed do eiusmod tempor incididunt ut labore \
et dolore magna aliqua.\
""";
또한 \s를 사용하면 후행 공백 제거를 방지할 수 있다.
아래처럼 사용하면 각 줄의 길이가 정확히 6자임을 보장한다.
String colors = """
red \s
green\s
blue \s
""";
'Study > Java' 카테고리의 다른 글
Spring Boot Dynamic Bean 등록 (0) | 2020.06.25 |
---|---|
Spring Rest Docs response body 한글 깨짐 문제 (mockmvc 설정 문제) (0) | 2020.06.19 |
spring reference 문서는 어떻게 만들어질까? (0) | 2020.06.12 |
[troubleshooting] 아직 명확한 해결법을 찾지 못한 Spring Boot web No ServletContext set 에러 현상 (0) | 2020.06.05 |
Spring Boot 2.3 Release Notes (0) | 2020.05.26 |
Spring Custom HandlerExceptionResolver 사용하기 (0) | 2020.02.18 |
재미로 보는 Spring Project release train naming (0) | 2020.02.07 |
OOP 개발 원칙 (0) | 2020.01.31 |
RestTemplate Generic responseType 사용 (0) | 2020.01.28 |
Reactor 언제 어떤 Operator를 써야 할까? (4) | 2020.01.21 |