JAVA 8
람다식
스트림
인터페이스 기본 메소드
메소드 선언 앞에 default, static 등의 예약어를 붙임으로써 인터페이스 단계에서 메소드를 구현할 수 있다.
상속받는 클래스마다 구현할 필요 없어져서 좋음!
Optional 클래스
공포의 NullPointerException을 방지하기 위해 관련 처리를 행하는 Optional 클래스를 이용해 null에 대한 대비를 할 수 있다.
JAVA 9
다이아몬드 연산자 확장
ArrayList<Type> list = new ArrayList<Type>();
을
ArrayList<Type> list = new ArrayList<>();
로 줄여 쓸 수 있다.
Immutable(불변) 컬렉션
List, Set, Map 인터페이스에서 제공하는 of, ofEntries 메소드를 통해 추가, 수정, 제거가 불가능한 컬렉션을 만들 수 있다.
컬렉션에서 추가,수정,제거를 없애면 사실상 문이 안 열리는 열차나 마찬가지인데 그런 컬렉션이 왜 필요한가요?
1. 다른 외부요인을 거쳐가더라도 데이터가 온전하기 때문에 안전하고, 예측이 쉽다.
2. Read만 가능하므로 다중 스레드 환경에서 동기화와 관련된 문제를 피할 수 있다.
3. 함수형 프로그래밍을 지원한다.
4. 성능이 높고, 코드가 간결해지고, 디버그가 쉬워지고, 메모리 누수를 방지할 수 있고, 확장성이 좋고....
자바 8에서도 만들 수 있지만 불편하다. 9 넘어와서 좀 편해지게 개선됨
JAVA 10
지역 변수의 타입 추론
ArrayList<Type> list = new ArrayList<>();
을
var list = new ArrayList<>()
로 줄여 쓸 수 있다.
근데 메소드 내에서 쓰이는 변수에 한정된다.
JAVA 11
람다식 타입 추론
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
을
Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
로 줄여 쓸 수 있다.
JAVA 12
Switch 표현식
switch(i) {
case 1:
System.out.println("1");
break;
case 2:
a += b;
break;
case 3:
case 4:
a /= b;
break;
}
을
switch(i) {
case 1 -> System.out.println("1");
case 2 -> a += b;
case 3, 4 -> a /= b;
}
로 줄여 쓸 수 있다.
또한 제어문으로만 사용했던 이전과 달리, 표현식으로도 사용할 수 있게 되었다...! 약간 아쉬운 점이 있다면, 표현식으로 작성할 경우 case에 단일문만 작성 가능하다는 것. 두 줄 이상 쓰면 컴파일러가 못 알아듣는다.
써먹기 좋은 함수가 하나 생긴 것 같은 기분으로 다음처럼 사용할 수 있다.
int d = switch(i) {
case 1 -> 5;
case 2, 3 -> 4;
default -> 1;
};
System.out.println(d);
다만 12버전에서는 프리뷰 기능이기 때문에, 컴파일러 옵션에 --enable-preview 옵션을 넣어야 한다.
JAVA 13
switch 표현식 2
int d = switch(i) {
case 1 -> 5;
case 2 -> 3;
case 3, 4 -> 1;
default -> 0;
}
을
int d = switch(i) {
case 1:
yield 5;
case 2:
yield 3;
case 3, 4:
yield 1;
default:
yield 0;
}
로도 쓸 수 있다. case의 ':'은 여전히 '->'로도 사용할 수 있다. 섞어서 쓰면 컴파일러가 하지 말라고 경고한다.
어차피 표현식으로 작성하면 단일문밖에 쓸 수 없는데 yield 명령어가 왜 필요한가요?
yield 명령어가 생긴 이유는 13 버전부터 표현식에도 복수의 코드를 작성할 수 있게 되었기 때문이다.
int d = switch(i) {
case 1: {
System.out.println("i가 말하길: 난 1이란다.");
yield 5;
}
case 2, 3: yield 4;
case 4: yield 3;
case 5, 6: yield 2;
default: {
System.out.println("i가 말하길: 난 1~6의 수가 아니란다.");
yield 1;
}
};
물론 다 때려치우고 그냥 제어문으로도 사용할 수 있다.
다중 문자열
String json = ""
+ "{\n"
+ "\t\"name\" : \"죽...여...줘.....\",\n"
+ "\t\"difficulty\" : \"very hard\"\n"
+ "}";
을
String newJson = """
{
"name" : "다중 문자열 쓰고 나의 성공 시절 시작됐다",
"difficulty" : "very easy"
}
""";
로 훠어어얼씬 편하게 작성할 수 있다. 핵심은 큰 따옴표 세 개로 맺고 끊는 것.
특수 문자를 표현하기 위해서 '\'를 쓰지 않아도 되니 문장이 훨씬 읽고 쓰기 쉬워진다.
System.out.printf("""
문장 1: %s
문장 2: %s
실수: %.02f
정수: %d""",
"""
다중
문자열도
간응!""", "보통의 문자열도 가능!", 3.121, 4);
이렇듯 문자열이 호환되는 모든 장소에서 사용할 수 있다.
JAVA 14
Record
class OldData {
final int a, b;
public OldData(int a, int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
@Override
public String toString() {
return this.getClass().getName() + "[a=" + a + ", b=" + b + "]";
}
};
을
record NewData(int a, int b) {};
로 줄일 수 있다...
record 키워드는 생성한 이후 바뀌지 않는, 위의 불변 컬렉션과 같이 수정 불가능한 자료를 다루고자 할 때 쓰인다.
자동으로 Getter, 생성자, equals, hashCode, toString 메소드를 만들어주므로 귀찮은 작업들을 전부 넘겨버릴 수 있고, 모든 내부 변수가 final로 선언되기 때문에 외부 흐름에서도 데이터가 안전하고, 스레드 친화적이다. 불변성을 가졌으니 그렇겠지...
이전 버전의 경우 Lombok이라는 외부 라이브러리를 쓰면 된다.
instanceof 개선
Object a = "아아, 모르는가? 문자열이라고 하는 것이지.";
if (a instanceof String) {
String text = (String)a;
System.out.println(text);
}
을
Object a = "아아, 모르는가? 문자열이라고 하는 것이지.";
if (a instanceof String text) {
System.out.println(text);
}
로 줄여 쓸 수 있다. 캐스팅 스킵!
'프로그래밍 > Java' 카테고리의 다른 글
| 람다식 (Lambda expression) (0) | 2024.02.17 |
|---|---|
| 컬렉션 프레임워크 (0) | 2024.02.12 |
| 스레드 ( Thread ) (0) | 2022.02.11 |
| 어노테이션 ( Annotation ) (0) | 2022.02.10 |
| java.io (0) | 2022.02.10 |