ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바를 조심스럽게 열어 보았다 - Switch 문
    Java&Spring/Java 2023. 5. 4. 21:31

    이전 블로그 포스팅에서는 자바의 스위치문이 if-else 문을 이용하는 것 보다 성능적으로 좋을 수 있다라는 이야기를 하였습니다.

     

    이번 글에서는  자바 12 이상의 표현에서 장점 , 동일성과 동등성의 개념을 이야가하며 스위치문의 문자열 매칭 방식의 대하여 알아봅니다.

     

    1. 람다 표현에서  문자열 생성의 장점

     

    자바 버전 12 이상에서 사용하는 람다 표현식을 활용하면 다음과 같이 작성 할 수 있습니다.

    public class Application {
        public static void main(String[] args) {
            int value = 4;
            switch (value){
                case 4 -> System.out.println(value + "this is four");
                case 1 -> System.out.println(value + "this is one");
            }
        }
    }

     

    위의 코드에대하여 바이트 코드는 다음과 같습니다.

     

    view -> show Bytecode

     

    INVOKEDYNAMIC 을 호출 하는 것을 확인 할 수 있습니다.

     

    ( 람다 표현식은 자바 8버전 부터 정식으로 도입이 되었습니다. )

     

    람다 표현식을 이용하면 조건에 맞는 반환할 문자열이 컴파일 시점에서 모두 생성되는것이 아닌 런타임시 동적으로 생성이 되어 메모리가 절약이됩니다.

     

    이로인하여 자바 12 이상의 Switch 문은 발생하지 않는 조건의 대햐여 불필요한 메모리 낭비가 없다라는 장점이 있습니다. 

     

     

    2. 스위치문의 문자열 일치 동작 방식 ?

     

    문자열을 넣은 예시에서 스위치 문에서 equals 를 사용할 것 같아 확인을 해보겠습니다.

     

    비교를 위한 if 문은 다음과 같습니다.

    public class Application {
        public static void main(String[] args) {
            String hi = "HI";
            if(hi.equals("HI")){
                System.out.println("GOOD!");
            }
        }
    }

     

    인텔리제이에서 프로그램 실행 후, view - >  show byte code 를  확인합니다.

    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z

    String.equals 를 호출하여 문자열 비교를 하는것을 확인 할 수 있습니다.

     

     

    이번에는 Switch Case 문으로 작성을 해보겠습니다.

        public static void main(String[] args) {
            String hi = "HI";
            switch (hi) {
                case "HI" -> System.out.println("Good!");
            }
        }

     

    인텔리제이에서 프로그램 실행 후, view - >  show byte code 를  확인합니다.

     

    Switch Case 문의 byte code 를 보면 hashCode() 를 먼저 호출 하는것을 알 수 가 있다.

     

    cf) hashCode() 메소드는 자바에서 객체의 고유값 주소를 가져오는 메소드입니다.

     

     

     

     

     

     

     

     

     

     

    switch 문은 비교를 위해 입력 값과 각각의 case 문에 선언된 값을 비교하는데, 이때 문자열 비교를 위해 String 클래스의 hashCode() 메소드를 사용한다.

    hashCode() 메소드는 객체의 해시 코드를 반환하고 이때 해시 코드는 객체를 식별하는 데 사용되며, 서로 다른 객체에서 동일한 해시 코드가 반환될 가능성이 있다 !!  (해시 충돌)

    switch 문에서 문자열을 사용할 때, 문자열의 해시 코드를 먼저 계산하여 일치하는 case 레이블을 찾고 일치하는 case 레이블에서 코드를 실행하는 것을 위의 코드로 알 수 있다.

     

     

    같은 해쉬 코드이다 , euqls 의 리턴값이 true 이다 = 동등한 객체이다.

    같은 해쉬 코드이다 , euqls 의 리턴값이 false 이다 = 다른 객체이다.

    다른 해쉬 코드이다 = 다른 객체이다.

    HashTable , HashSet 등 Hash Collection 의 비교 논리와 같다.

     

    하지만 서로 다른 두 객체는 같은 해시코드를 가질 수 있다. , hashCode 의 반환 값이 int 이기 때문에 비둘기 집의 원리로 객체를 무한하게 서로 다르게 생성 할 수 없다. 

Designed by Tistory.