스위치문과 null (switches and null)
전통적으로, switch 문과 표현식은 선택기 표현식이 null을 검증할 때, NullPointerException을 throw 합니다. 따라서 null을 테스트하기 위해 switch 바깥에서 테스트해야 했습니다.
// Prior to Java 21
static void testFooBarOld(String s) {
if (s == null) {
System.out.println("Oops!");
return;
}
switch (s) {
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
}
java 21부터는 선택기 표현식의 값이 null일 때 switch의 동작은 항상 case 레이블에 의해 결정됩니다. case null이 있는 경우, switch는 해당 레이블과 관련된 코드를 실행합니다.
// As of Java 21
static void testFooBarNew(String s) {
switch (s) {
case null -> System.out.println("Oops");
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
}
케이스 미세화(Case reflnement)
패턴을 사용하는 case 레이블은 상수를 사용하는 경우와 달리 많은 값에 적용될 수 있습니다. 이는 종종 switch 규칙의 오른쪽에 조건부 코드를 사용하게 됨을 의미합니다.
// As of Java 21
static void testStringOld(String response) {
switch (response) {
case null -> { }
case String s -> {
if (s.equalsIgnoreCase("YES"))
System.out.println("You got it");
else if (s.equalsIgnoreCase("NO"))
System.out.println("Shame");
else
System.out.println("Sorry?");
}
}
}
여기서의 문제는 단일 패턴을 사용하여 케이스를 구별하는 것이 단일 조건을 넘어 확장되지 않는다는 것입니다. 여러 패턴을 작성하는 것이 좋겠지만, 그러려면 패턴을 세밀하게 표현할 수 있는 방법이 필요합니다. 따라서 switch 블록에서 패턴 case 레이블에 가드를 지정할 수 있는 when 절을 허용합니다. 이러한 접근 방식으로 가드를 사용하여 위의 코드를 다시 작성할 수 있습니다.
// As of Java 21
static void testStringNew(String response) {
switch (response) {
case null -> { }
case String s
when s.equalsIgnoreCase("YES") -> {
System.out.println("You got it");
}
case String s
when s.equalsIgnoreCase("NO") -> {
System.out.println("Shame");
}
case String s -> {
System.out.println("Sorry?");
}
}
}
이로써, switch 프로그래밍의 더 읽기 쉬운 스타일을 이끌어냅니다. 테스트의 복잡성이 switch 규칙의 왼쪽에 나타나고, 해당 테스트가 충족되는 경우 적용되는 로직이 switch 규칙의 오른쪽에 나타납니다. 이를 통해 보다 읽기 좋은 스위치 문 작성이 가능해집니다.
// As of Java 21
static void testStringEnhanced(String response) {
switch (response) {
case null -> { }
case "y", "Y" -> {
System.out.println("You got it");
}
case "n", "N" -> {
System.out.println("Shame");
}
case String s
when s.equalsIgnoreCase("YES") -> {
System.out.println("You got it");
}
case String s
when s.equalsIgnoreCase("NO") -> {
System.out.println("Shame");
}
case String s -> {
System.out.println("Sorry?");
}
}
}
case 상수, case 패턴 및 null 레이블이 조합되어 switch 프로그래밍의 새로운 기능을 보여주며, 비즈니스 로직과 혼합되었던 복잡한 조건 로직을 읽기 쉬운 순차적인 switch 레이블 목록으로 단순화할 수 있음을 보여줍니다.
스위치문과 열거형 상수(Switches and enum constants)
java 21전에는 case문에서 enum 상수를 사용하는 것은 매우 제한적입니다. switch문의 표현식은 enum 유형이어야 하며, 레이블은 enum 상수의 단순한 이름이어야 합니다.
// Prior to Java 21
public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
static void testforHearts(Suit s) {
switch (s) {
case HEARTS -> System.out.println("It's a heart!");
default -> System.out.println("Some other suit");
}
}
패턴 레이블을 추가한 후에도, 이 제약은 불필요하게 장황한 코드를 유발합니다.
// As of Java 21
sealed interface CardClassification permits Suit, Tarot {}
public enum Suit implements CardClassification { CLUBS, DIAMONDS, HEARTS, SPADES }
final class Tarot implements CardClassification {}
static void exhaustiveSwitchWithoutEnumSupport(CardClassification c) {
switch (c) {
case Suit s when s == Suit.CLUBS -> {
System.out.println("It's clubs");
}
case Suit s when s == Suit.DIAMONDS -> {
System.out.println("It's diamonds");
}
case Suit s when s == Suit.HEARTS -> {
System.out.println("It's hearts");
}
case Suit s -> {
System.out.println("It's spades");
}
case Tarot t -> {
System.out.println("It's a tarot");
}
}
}
guarded patterns을 사용하는 대신 열거형 상수에 대해 별도의 case문을 사용할 수 있습니다. 따라서 case 표현식이 열거형이어야 한다는 제한 조건을 완화하고 case문에 사용되는 상수가 열거형 상수를 사용할 수 있도록 허용합니다. 이를 통해 위의 코드를 다음과 같이 작성할 수 있습니다.
// As of Java 21
static void exhaustiveSwitchWithBetterEnumSupport(CardClassification c) {
switch (c) {
case Suit.CLUBS -> {
System.out.println("It's clubs");
}
case Suit.DIAMONDS -> {
System.out.println("It's diamonds");
}
case Suit.HEARTS -> {
System.out.println("It's hearts");
}
case Suit.SPADES -> {
System.out.println("It's spades");
}
case Tarot t -> {
System.out.println("It's a tarot");
}
}
}
이제 guarded type patterns을 사용하지 않고도 각 enum 상수에 대한 직접적인 case문을 사용할 수 있습니다.
'Language > JAVA' 카테고리의 다른 글
[JAVA] HashMap에 대해서(Thread Safe, 해시맵 동작 원리, chaining, 해시 충돌(Hash Collision), Fail-Fast ) - 컴도리돌이 (0) | 2024.04.24 |
---|---|
[Java] 서블릿 컨테이너(Servlet Container)에 대해서 - 컴도리돌이 (0) | 2024.03.04 |
[JAVA][백준 18110][구현] solved.ac - 컴도리돌이 (0) | 2024.01.26 |
[JAVA] 자바 8 이후 스태틱 객체가 GC 대상이 된 이유 - 컴도리돌이 (0) | 2024.01.17 |
[JAVA][백준 11062][게임 이론][DP] 카드 게임 - 컴도리돌이 (0) | 2022.08.21 |