우테코 프리코스를 시작하기 전에는 JDK 11을 사용하였었다. JDK 11를 사용하면서 아직 불편한 점도 없었지만 프리코스를 시작하면서 JDK17 버전을 사용 하라는 문구를 보고 단순히 17 다운받아서 11처럼 사용해도 될 것 같았지만 JDK 17 버전에서 새롭게 생긴 부분이나, 추가 된 메서드 등을 학습해서 적극적으로 문제에 적용해 보기 위해 작성하게 되었다.
https://dzone.com/articles/whats-new-between-java-11-and-java-17 문서를 통해 참고 하였다.
strip: 문자열 공백 제거 (기존 “trim()”이 ‘\u0020’ 이하 공백만을 제거 하였다면, “strip()”은 유니코드의 공백들을 전부 제거)
stripLeading: 문자열 앞의 공백을 제거
stripTrailing: 문자열 뒤의 공백을 제거
이건 진짜 몰랐는데 ...
String text = "{\n" +
" \"name\": \"김정훈\",\n" +
" \"age\": 26,\n" +
" \"address\": \"서울시 송파구"\n" +
"}";
System.out.println(text);
Java11에서는 JSON 같은 문자열이 필요할때 아래 와 같은 이스케이프 처리로 가독성이 많이 안좋았지만,
위와 같은 방식대로 개발을 하였다면 JDK 17 버전에서는 아래와 같은 표현방식이 가능하다.
String text = """
{
"name": "김정훈",
"age": 26,
"address": "서울시 송파구"
}
""";
System.out.println(text);
위에 text 형식을 보면 큰 따옴표 세개를 통해 이전 이스케이프 방식보다 쉽게 사용 할 수 있다.
마지막 큰 따옴표는 텍스트 블록의 시작 위치
를 나타내며 왼쪽으로 이동하게되면 각 줄 앞에
아래와 같이 2개의 공백을 출력한게 된다 .
// result 1
{
"name": 김정훈,
"age": 26,
"address": "서울시 송파구"
}
마지막 큰따옴표를 아래와 같이 오른쪽
으로 옮겼다면 텍스트 블록의 시작이 첫 번째 문자에 의해 결정된다.
String text = """
{
"name": "김정훈",
"age": 26,
"address": "서울시 송파구"
}
""";
// result 2
{// result 1과 다르게 대괄호 시작하는 부분 앞에 공백이 없다
"name": 김정훈,
"age": 26,
"address": "서울시 송파구"
}
기존에 switch문 방식은 아래와 같다.
switch (hobby) {
case "영화": {
System.out.println("영화");
break;
}
case "게임" : {
System.out.println("게임");
break;
}
}
하지만 아래와 같이 바뀐 Switch문을 보면 정말 가독성이 좋아진걸 확인 할 수 있다.
switch (hobby) {
case "영화" -> System.out.println("영화");
case "게임" -> System.out.println("게임");
default -> System.out.println("case에 없다");
}
몰랐던 부분이지만 출력문안에서도 가능하다고 하네요 ?!
System.out.println(
switch (hobby) {
case "게임"-> "좋아하는 취미";
case "오잉" -> "이건 취미가 아닌데";
default -> "취미가 없네 ?"
}
);
Records는 현재 모르고 있는 부분을 새롭게 알게되는 부분이였다. Records는 JDK 14 버전일때 나온 것 같다.
레코드는 불변(immutable) 한 데이터 객체를 쉽게 생성할 수 있도록 하는 새로운 유형의 클래스이다.
기존에 불변한 데이터를 만들려고 한다면 아래와 같이 작성하였다.
public class User{
private final String userName;
privae final int age;
public Person(String userName, int age) {
this.userName = userName;
this.age = age;
}
public int getAge(){
...
}
public String toString() {
...
}
public int hashCode(){
}
public boolean equals(){
}
...
}
기존 스프링 프로젝트를 사용할때는 @ToString등 어노테이션을 적용해서 적용해서 사용하였지만, JDK17를 적용해서 사용한다면 더 쉽게 적용할 수 있을것같다.
아래는 레코드를 사용할 때 코드이다.
public record User(String userName, int age){
}
JDK15에서 제공되었던 Sealed Class가 JDK 17 에서 추가 되었다. Sealed Class는 interface나 class 상속, 구현 등 클래스를 지정된 해당 클래스만 상속 이나 구현을 하게 하는 기능 입니다. 쉽게 말해 봉인된 클래스입니다.
public sealed class Computer permits Mouse,KeyBoard{}
public boolean equals(Object obj){
if(obj instanceof User){
User uesr = (User) obj;
...
}
}
객체 타입이 object인지 확인하기 위해 기존에 casting하는 과정이 있었지만 캐스팅 없이도 참조변수를 스코프안에 넣을 수 있다.
public boolean equals(Object obj){
if(obj instanceof User user){
...
}
기존에 Java11에서 사용할때 null
값이 들어갔을 경우
Exception in thread "main" java.lang.NullPointerException
at com.example.Application.HelpfulNullPointerExceptions.main(HelpfulNullPointerExceptions.java:13)
위 사진처럼 줄 번호 만 표시되는 부분이 있었지만, 어떤 메서드인지 분명하게 알 수 없었는데
17버전 부터는 정확한 발생 위치를 알려주게됩니다.
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null
at example.Application.main(Application.java:15)
JDK 11 에서는 getCompactNumberInstance
라는 메서드가 없었습니다, 하지만 JDK17부터는
getCompactNumberInstance
메서드를 통해 숫자 형식을 보다 간결하게 지정 할 수 있게 되었습니다.
//SHORT
NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.ENGLISH, NumberFormat.Style.SHORT);
System.out.println(fmt.format(1000));
System.out.println(fmt.format(100000));
System.out.println(fmt.format(1000000));
//LONG
NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.ENGLISH, NumberFormat.Style.LONG);
System.out.println(fmt.format(1000));
System.out.println(fmt.format(100000));
System.out.println(fmt.format(1000000));
//SHORT style
1K
100K
1M
// LONG style
1 thousand
100 thousand
1 million
오... 신기하다....
JDK 11 버전을 사용할때 아래와 같이 사용하였다. 하지만 JDK 17에서는 조금 더 간결하게 사용 가능한 toList()
로 바뀌었다.
JDK 11
Stream<String> stream = Stream.of("1","2","3");
List<String> list = stream.collect(COllectors.toList());
JDK 17
Stream<String> stream = Stream.of("1","2","3");
List<String> list = stream.toList();