[Java] 문자열 비교, equals()와 ==의 차이 이유

    자바를 배우는 초창기에는 문자열의 비교시 ==를 사용하여 예상치 못한 에러가 발생하는 경우가 종종 발생한다. 대개 true로 문제가 없는 경우도 많지만, 간혹 false가 떨어지곤 하는데 이 이유에 대해서 설명해보고자 한다.

     

    [Java] 문자열 비교, equals()와 ==의 차이 이유


    자바 예시

    String str1 = "삼성전자";
    String str2 = "삼성전자";
    String str3 = new String("삼성전자");
    
    System.out.println(str1 == str2);
    System.out.println(str1 == str3);
    System.out.println(str1.equals(str3));

     

    위 예시를 해보면, 결과가 아래와 같이 떨어진다.

     

    true
    false
    true

     

    결과에 대한 원인

    str1과 str2는 새로운 객체가 아니기 때문에 같은 주소를 바라본다. 즉, 변수가 다르다 하더라도 해당 값이나 새로운 객체로 생성되지 않는 이상 같은 주소값을 가르키게 된다. 즉 위의 내용의 ==에서 첫번째 str1과 str2의 경우 true가 된 이유는 두 객체가 동일한 메모리 위치를 가르키기 때문이다.

     

    반면, str3의 경우 new를 사용하여 새로운 메모리를 생성하였는데 새로운 메모리를 할당할 경우 전혀 다른 주소가 생성된다. equals 메소드의 경우 순수 값을 비교 하는 메소드이기 때문에 주소가 다른 객체라 하더라도 문자열 비교가 가능하다. 

     

    아래는 equals의 내부 로직이다.

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

     

    equals를 보면, 첫번째 객체가 같을 경우 return을 한 후, 객체가 다를 경우 처리하는 로직을 보면, char로 한값 한값 비교해서 값이 다르면, false를 리턴하는 구조로 되어 있다.

     

    고민하지 말고 문자열은 equals 계열

    사실 위와 같이 주소값 어쩌고 고민을 하는 것보다 문자열일때에는 equals를 쓰도록 하자. 개발 년차가 되는 사람들 중 문자열일 경우 ==를 쓰는 사람을 본적이 없다. 어차피 equals 내부 로직에도 객체를 비교하는 ==를 부분이 있기 때문에 퍼포먼스면에서도 둘의 차이는 없다고 봐도 무방하다. 

     

     

    반응형

    댓글

    Designed by JB FACTORY