자바 스위치 문

1. 개요

이 자습서에서는 switch 문이 무엇 이며 사용 방법에 대해 알아 봅니다 .

스위치 문은 우리가 여러 가지 중첩 된 대체 할 수 있는 경우 - 다른 구조를 따라서 우리의 코드의 가독성을 향상시킬 수 있습니다.

스위치 는 시간이 지남에 따라 발전했습니다. 특히 Java 5 및 7에서 새로운 지원 유형이 추가되었습니다. 또한 계속 발전하고 있습니다. 스위치 식은 Java 12에 도입 될 것입니다.

아래에서는 switch 문 사용, break 문의 역할 , switch 인수 / 케이스 값에 대한 요구 사항 및 switch 문 에서 String 비교 를 보여주는 몇 가지 코드 예제를 제공 합니다.

예제로 넘어 갑시다.

2. 사용 예

다음과 같은 중첩 된 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 문 을 종료하는 데 사용됩니다 .

3. 휴식 진술

실제 생활에서 대부분의 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 문을 추가 해야합니다.

중단 이 필요하지 않은 유일한 블록 은 마지막 블록 이지만 마지막 블록에 중단 을 추가 하면 코드의 오류 발생 가능성이 줄어 듭니다.

또한 여러 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; }

4. 인수 및 케이스전환

이제 허용되는 유형의 switch 인수 및 케이스 값, 이에 대한 요구 사항 및 switch 문이 문자열과 함께 작동 하는 방식에 대해 설명하겠습니다 .

4.1. 데이터 유형

switch 문 에서 모든 유형의 객체와 기본 형식을 비교할 수는 없습니다 . 스위치는 와뿐만 아니라 네 개의 기본 요소와 그 래퍼와 함께 작동 열거 형문자열 클래스 :

  • 바이트바이트
  • 짧은짧은
  • intInteger
  • 문자문자
  • 열거 형

문자열 유형은 Java 7로 시작 하는 switch 문 에서 사용할 수 있습니다 .

enum 유형은 Java 5에서 도입되었으며 그 이후로 switch 문 에서 사용할 수 있습니다 .

래퍼 클래스는 Java 5부터 사용할 수 있습니다.

물론 스위치 인수와 케이스 값은 동일한 유형이어야합니다.

4.2. null없음

null 값을 switch 문에 인수로 전달할 수 없습니다 . 이렇게하면 프로그램은 첫 번째 스위치 예제를 사용하여 NullPointerException을 발생 시킵니다 .

@Test(expected=NullPointerException.class) public void whenSwitchAgumentIsNull_thenNullPointerException() { String animal = null; Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); }

물론 switch 문의 case 레이블에 null 을 값으로 전달할 수도 없습니다 . 그렇게하면 코드가 컴파일되지 않습니다.

4.3. 컴파일 시간 상수로서의 케이스

If we try to replace the DOG case value with the variable dog the code won't compile until we mark the dog variable as final:

final String dog="DOG"; String cat="CAT"; switch (animal) { case dog: //compiles result = "domestic animal"; case cat: //does not compile result = "feline" }

4.4. String Comparison

If a switch statement used the equality operator to compare strings we couldn't compare a String argument created with the new operator to a String case value correctly.

Luckily, the switch operator uses the equals() method under the hood.

Let's demonstrate this:

@Test public void whenCompareStrings_thenByEqual() { String animal = new String("DOG"); assertEquals("domestic animal", s.exampleOfSwitch(animal)); }

5. switch Expressions

JDK 13 is now available and brings an improved version of a new feature first introduced in JDK 12: the switch expression.

In order to enable it, we need to pass –enable-preview to the compiler.

5.1. The New switch Expression

Let's see what the new switch expression looks like when switching over months:

var result = switch(month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1; case MARCH, MAY, APRIL, AUGUST -> 2; default -> 0; }; 

Sending in a value like Month.JUNE would set result to 3.

Notice that the new syntax uses the ->operator instead of the colon we're used to with switch statements. Also, there's no break keyword: The switch expression doesn't fall through cases.

Another addition is the fact that we can now have comma-delimited criteria.

5.2. The yield Keyword

Going a bit further, there's a possibility to obtain fine-grained control over what's happening on the right side of the expression by using code blocks. In such a case, we need to use the keyword 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; };

While our example is a bit arbitrary, the point here is that we've got access to more of the Java language here.

5.3. Returning Inside switch Expressions

As a consequence of the distinction between switch statements and switch expressions, it is possible to return from inside a switch statement, but we're not allowed to do so from within a switch expression.

The following example is perfectly valid and will compile:

switch (month) { case JANUARY, JUNE, JULY -> { return 3; } default -> { return 0; } }

However, the following code will not compile, as we are trying to return outside of an enclosing switch expression:

var result = switch (month) { case JANUARY, JUNE, JULY -> { return 3; } default -> { return 0; } };

5.4. Exhaustiveness

When using switch statements, it doesn't really matter if all cases are covered.

The following code, for example, is perfectly valid and will compile:

switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER -> 1; }

For switch expressions though, the compiler insists that all possible cases are covered. The following code snippet, for example, would not compile, as there's no default case and not all possible cases are covered:

var result = switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER -> 1; }

The switch expression, however, will be valid when all possible cases are covered, like in the following example:

var result = switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1; case MARCH, MAY, APRIL, AUGUST -> 2; }

Please note that the above code snippet does not have a default case. As long as all cases are covered, the switch expression will be valid.

6. Conclusion

이 튜토리얼에서 우리는 Java 에서 switch 문 을 사용하는 미묘한 점을 배웠습니다 . 가독성과 비교 값의 유형에 따라 스위치 사용 여부를 결정할 수 있습니다 .

switch 문은 미리 정의 된 집합 (예 : 요일)에 제한된 수의 옵션이있는 경우에 적합한 후보입니다. 그렇지 않으면 새 값이 추가되거나 제거 될 때마다 코드를 수정해야하므로 실행 불가능할 수 있습니다. 이러한 경우 다형성 또는 Command와 같은 다른 디자인 패턴과 같은 다른 접근 방식을 고려해야합니다.

항상 그렇듯이 전체 JDK 8 코드 및 JDK 13 코드는 GitHub에서 사용할 수 있습니다.