본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


JAVA

JAVA 스터디 5 - switch expression (자바 12부터 추가됨)

반응형
자바 12부터 새로운 switch문이 추가 되었다 . 
 
기존 switch 제어문의 불편함 
1. 변수은 값이 다르지만 공통된 명령을 수행해야 할때 case를 추가해서 똑같은 코드를 또 적어야한다 .
2. case 내에 break;를  포함시키지 않으면 조건이 해당 케이스에 맞는 명령이 실행된 후에도 코드가 계속되게 된다.
3. return값이 존재할 수 없다 .

switch expression
 자바 12부터 지원되었으며 13에선 yeild의 사용이 추가되었다 . 기본 자바의 switch문은 c 와 c++같은 언어를 따르기 때문에 
제어 흐름이 낮은 수준의 코드 (바이너리 코드) 작성하는데 더 유용하지만 실제로 switch는 높은 수준의 컨텍스트에서 사용되기 때문에 오류가 발생하기 쉬운 특성을 갖고 있었다 (위의 switch 제어문의 불편함과 같은)
  위와 같은 불편함을 해결하기 위해 몇가지 새로운 형식으로 switch expression이 만들어 졌다 ,
아래의 코드를 보며 살펴보자 , 현재 자바 버전이 11이기 때문에 JDK 15를 받아 cmd를 통해 해당 15버전의 javac 와 java명령어를 사용하여 실행시켜 보았다 .  

1.람다식 활용과 공통의 메서드를 수행하는 케이스를 한번에 정의
         OpenJDK  document에 Switch expression 예제 코드이다 

Switch expression의 흐름은 기존의 switch 문과 같다 .   각각의 케이스들이 정의되어 있으며 그에 따른 명령코드가 화살표 함수로 구현되어 있다 . 또 같은 명령을 수행하는 여러가지 케이스가 한번에 정의되 있는게 특징이다 .  

위의 코드에서 변수 day의 참조값인 "MONDAY" 는 첫 번째 case에 해당함으로 6이 찍힌다 . 

2.값을 리턴 받을 수 있음 , break;가 필요없음

기존의 switch문으로 공통 변수를 사용하는 코드이다. 똑같은 내용의 반복이 많고 , break;를 빼먹으면 해당 케이스는 누락될 수 있어 오류가 발생하기 쉽다.


부합하는 케이스에서  람다식을 활용하여 화살표 오른쪽 값이 바로 리턴되며 거기서 switch문이 끝나고(break;가 필요 없음) 값이 리턴되어 int numLetters에 들어간다 . 이 경우엔 default에 에러를 던져줘야 했다 . 
에러를 던지지 않을 경우 'switch' expression does not cover all possible input values <-이런 컴파일 에러가 발생한다. switch expression이  인풋 값에 대해 커버할 수 없으니 예외를 던지라는 얘기인 것 같다.  내부적으로 지금과 같이 변수를 리턴 받는 경우에는 default를 정의해야 한다는게 정해져 있는 것 같다 . (아시는분 댓글 좀 달아주세요!)
아 document를 좀 읽어보니 아래와 같이 써있었다 .
In turn, extending switch to support expressions raises some additional needs, such as extending flow analysis (an expression must always compute a value or complete abruptly), and allowing some case arms of a switch expression to throw an exception rather than yield a value.
  음  


document에서 같은 얘기를 계속하는 것 같은데  이런 방식으로도 사용할 수 있다 한다 .

메서드안에서의 switch expression 활용 이고 메서드의 파라미터가 swich문의 인자로 들어왔고  알맞은 라벨에 맞는 명령어가 실행된다
출력값은
one
two
many

위의 코드를 더 확장시키면 요런식으로도 가능하다 .

System.out.println()안에 스위치 문을 넣어서 불필요한 코드가 줄고 더 간결해 졌다 . 

3. yield 예약어로 값 return 


위의 코드 흐름을 보면 먼저 스위치문 파라미터로 day "qweqwe" 라는 값이 들어가고 일치하는 case가 없기 떄문에 default 로 넘어가고 default에서는  day 길이를  k에 담았고 k를 result에 담고 yield 예약어를 활용해 result를 리턴했다 . int j = result인 샘이다 . 
 출력은 
 

요렇게 나온다 . switch문에 저렇게 코드를 담는다는게 새롭다 . 기존 switch문과 다르게 값을 yield 예약어를 통해  return 시켜주기 때문에 가능한 일이다.

아래와 같은 방식으로 기존 switch 문의 "case L :" 라벨을 사용하여 switch문을 만들수도있다 .

출력
 resultValue = 1

break와 yield는   switch statements와 switch expressions를 구분 짓기에 용이하다 . switch statements는 break의 타겟이 될수있고 , switch expressionsdms yield의 타겟이 될수 있다. break는 yield로 대체할 수 있다 .


switch expressions를 사용할 때 주의 점이 있다.  
-모든 벨류는 철저하게  그에 매칭하는 switch 라벨이 있어야 한다 .  무슨말인가 코드를 살펴 보면

이 코드를 보니 뭔가 위에 떴던  'switch' expression does not cover all possible input values 에러가 이해가간다 . 
메서드를 생각하면 될 것같다 return type이 int인 메서드에 리턴 값이 없는 것과 같은 경우이다. int i로 switch 값의 결과물을 리턴 받는다 선언해 놓고선 아무것도 리턴시키지 않았기 때문에 컴파일 에러가 발생한다 . 
 선언한 변수와 다른 리턴타입을 보내도 에러가 발생한다 .

 

반응형