안녕하세요.
프로그래밍을 수행하다보면 Switch-Case 문을 종종 작성할 때가 있는데요.
활용 방안과 JDK 13 부터 변화된 문법도 살펴보도록 하겠습니다.
Switch-Case 문을 잘 활용할 경우
If-Else 구문을 대체할 수 있는 가독성 좋은 코드로 탄생합니다~
사용 예
다음과 같은 중첩된 if-else 문 이 있다고 가정해 보겠습니다 .
public String exampleOfIF(String animal) {
String result;
if (animal.equals("DOG") || animal.equals("CAT")) {
result = "domestic animal";
} else if (animal.equals("TIGER")) {
result = "wild animal";
} else {
result = "unknown animal";
}
return result;
}
위의 코드는 보기에 좋지 않고 유지 관리하고 추론하기 어려울 것입니다.
가독성을 높이기 위해 switch 문을 사용할 수 있습니다.
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG":
result = "domestic animal";
break;
case "CAT":
result = "domestic animal";
break;
case "TIGER":
result = "wild animal";
break;
default:
result = "unknown animal";
break;
}
return result;
}
우리는 switch 인수 animal 을 여러 케이스 값과 비교합니다. 케이스 값 중 인수와 같은 값이 없으면 기본 레이블 아래의 블록이 실행됩니다.
간단히 말해 break 문은 switch 문 을 종료하는 데 사용됩니다 .
break 문
실생활에서 대부분의 switch 문은 case 블록 중 하나만 실행되어야 함을 의미하지만 블록이 완료된 후 스위치 를 종료하려면 break 문을 사용해야 합니다 .
break 를 쓰는 것을 잊었다면 아래 블록이 실행될 것입니다.
이를 보여주기 위해 break 문을 생략하고 각 블록의 콘솔에 출력을 추가해 보겠습니다.
public String forgetBreakInSwitch(String animal) {
switch (animal) {
case "DOG":
System.out.println("domestic animal");
default:
System.out.println("unknown animal");
}
}
이 코드 forgetBreakInSwitch ( "DOG") 를 실행하고 모든 블록이 실행되는지 확인하기 위해 출력을 확인합니다.
domestic animal
unknown animal
따라서 다음 레이블 아래의 코드로 전달할 필요가 없는 한 주의하고 각 블록 끝에 break 문을 추가해야 합니다.
break 가 필요하지 않은 유일한 블록 은 마지막 블록 이지만 마지막 블록에 break 를 추가하면 코드에서 오류가 발생하기 쉽습니다.
여러 case 문에 대해 동일한 코드를 실행하려는 경우 이 동작을 활용하여 break 를 생략 할 수도 있습니다.
처음 두 경우를 그룹화하여 이전 섹션의 예를 다시 작성해 보겠습니다.
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG":
case "CAT":
result = "domestic animal";
break;
case "TIGER":
result = "wild animal";
break;
default:
result = "unknown animal";
break;
}
return result;
}
인수 및 케이스 값 전환
이제 허용되는 유형의 switch 인수 및 케이스 값, 이에 대한 요구 사항 및 switch 문이 문자열과 함께 작동하는 방식에 대해다뤄봅니다.
데이터 유형
switch 문 에서 모든 유형의 개체와 기본 요소를 비교할 수는 없습니다 . 스위치 는 4개의 프리미티브와 해당 래퍼, enum 유형 및 String 클래스 에서만 작동합니다 .
byte and Byte
short and Short
int and Integer
char and Character
enum
String
문자열 유형은 Java 7부터 switch 문에서 사용할 수 있습니다.
enum 유형은 Java 5에서 도입되었으며 그 이후로 switch 문에서 사용할 수 있습니다.
래퍼 클래스도 Java 5부터 사용할 수 있습니다.
물론 switch 인자와 case 값은 같은 타입이어야 합니다.
null 값 없음
null 값을 switch 문의 인수로 전달할 수 없습니다 .
그렇게 하면 프로그램은 첫 번째 스위치 예제 를 사용하여 NullPointerException 을 throw합니다.
@Test(expected=NullPointerException.class)
public void whenSwitchAgumentIsNull_thenNullPointerException() {
String animal = null;
Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
}
물론 switch 문의 case 레이블에 값으로 null 을 전달할 수도 없습니다. 그렇게 하면 코드가 컴파일되지 않습니다.
컴파일 시간 상수로서의 케이스 값
DOG 케이스 값을 dog 변수 로 바꾸려고 하면 dog 변수를 final 로 표시할 때까지 코드가 컴파일되지 않습니다 .
final String dog="DOG";
String cat="CAT";
switch (animal) {
case dog: //compiles
result = "domestic animal";
case cat: //does not compile
result = "feline"
}
문자열 비교
switch 문 이 문자열을 비교하기 위해 등호 연산자를 사용한 경우 new 연산자 로 생성 된 String 인수 를 String 케이스 값과 올바르게 비교할 수 없습니다.
운 좋게도 스위치 연산자는 내부적으로 equals() 메서드를 사용합니다.
@Test
public void whenCompareStrings_thenByEqual() {
String animal = new String("DOG");
assertEquals("domestic animal", s.exampleOfSwitch(animal));
}
스위치 식
이제 JDK 13 을 사용할 수 있으며 JDK 12 에 처음 도입된 새로운 기능인 스위치 표현식 의 개선된 버전을 제공합니다 .
활성화 하려면 컴파일러에 –enable-preview 를 전달해야 합니다 .
새로운 스위치 표현식
몇 개월에 걸쳐 전환할 때 새로운 switch 표현식이 어떻게 보이는지 봅시다 .
var result = switch(month) {
case JANUARY, JUNE, JULY -> 3;
case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1;
case MARCH, MAY, APRIL, AUGUST -> 2;
default -> 0;
};
Month.JUNE 와 같은 값을 보내면 결과 가 3 으로 설정 됩니다 .
새 구문은 우리가 switch 문 에 익숙했던 콜론 대신 -> 연산자를 사용합니다. 또한 break 키워드 가 없습니다. switch 표현식은 case s를 통과하지 않습니다.
또 다른 추가 사항은 이제 쉼표로 구분된 기준을 가질 수 있다는 사실입니다.
yield 키워드 _
조금 더 나아가서 코드 블록을 사용하여 표현식의 오른쪽에서 일어나는 일을 세밀하게 제어할 수 있습니다.
이 경우 yield 키워드를 사용해야 합니다 .
var result = switch (month) {
case JANUARY, JUNE, JULY -> 3;
case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1;
case MARCH, MAY, APRIL, AUGUST -> {
int monthLength = month.toString().length();
yield monthLength * 4;
}
default -> 0;
};
내부 스위치 표현식 반환
switch 문과 switch 식을 구분한 결과로 switch 문 내에서 반환 할 수 있지만 switch 식 내에서 반환 할 수 없습니다 .
다음 예제는 완벽하게 유효하며 컴파일됩니다.
switch (month) {
case JANUARY, JUNE, JULY -> { return 3; }
default -> { return 0; }
}
그러나 둘러싸는 스위치 표현식 외부 에서 반환 을 시도하기 때문에 다음 코드는 컴파일되지 않습니다 .
var result = switch (month) {
case JANUARY, JUNE, JULY -> { return 3; }
default -> { return 0; }
};
댓글