자바에서 코드를 작성하며 String을 비교하는 경우는 매우 많습니다.

보통 int나 char 타입의 경우 '==' 비교를 많이 사용합니다만, String의 경우 대부분 == 비교를 사용하면 안됩니다.

 

== 과 .equals() 의 차이

  • == 비교는 참조하는 객체가 동일한지를 비교합니다. 
  • .equals() 비교는 값 자체가 동일한지를 비교합니다.

String 비교시 대부분의 경우는 값 자체가 동일한지를 비교하므로 == 비교가 아닌 .equals() 비교를 해야합니다.

 

간단한 테스트 코드를 보겠습니다.

// 값에 대한 비교이므로 동일
new String("test").equals("test") // true 

// new String()으로 새로운 객체를 생성하여 같은 객체끼리 동일한지 비교
// 서로 참조하는 객체가 다르므로 false
new String("test") == "test" // false 
new String("test") == new String("test") // false 

// "test" 스트링 리터럴은 컴파일러에 의해 interned 되므로
// 같은 객체끼리 비교하는 것이 됨
"test" == "test" // true 

// 스트링 리터럴은 컴파일러에 의해 조립되어("te" + "st" = "test") interend 되므로 
// 같은 객체끼리 비교하는 것이 됨
"test" == "te" + "st" // true

// Objects.equals()로 null을 포함하여 값 비교가 가능함
Objects.equals("test", new String("test")) // true
Objects.equals(null, "test") // false
Objects.equals(null, null) // true

string의 값 비교를 위해서는 .equals()나 Object.equals()를 사용할 수도 있고,

대소문자를 신경쓰지 않고 비교하는 String.equalsIgnoreCase() 같이 추가기능이 있는 비교메서드를 사용할 수 있습니다.

 

String intern

위 내용 중 string intern에 대해 추가설명을 드리자면,

자바는 JVM에 문자열 풀(pool)을 생성 후, 새로운 문자열이 사용되면 그 풀에 등록하여 놓습니다.

만일 그 문자열이 다시 사용되는 경우 새로 생성하는 것이 아닌 문자열 풀에서 꺼내 사용하는 것이지요. 왜냐하면 String 객체는 불변이기 때문에 동일한 객체를 계속 생성하는 것이 아니라 생성 후 공유하는 특징을 가지기 때문입니다.

 

String 객체에 대해 intern된 값을 가져올 수도 있는데요 이를위해 String 클래스의 intern()을 사용할 수 있습니다.

아래 테스트 코드를 보시죠.

 

str1과 str2는 String intern에 의해 JVM 문자열 풀의 같은 String 객체를 참조합니다. 

str1.intern() 은 JVM 문자열 풀에서 str1과 값이 동일한 String 객체를 가져옵니다. 만일 풀에 저장되어 있지 않다면 신규로 등록후 가져오게 되지요. 

str1.intern() 과 str2.intern()은 JVM 문자열 풀의 같은 객체를 가져오므로 동일합니다. 

 

str3과 str4는 new String()으로 생성된 각기 다른 String 객체를 참조합니다.

하지만 str1 ~ str4 의 intern() 호출은 결국 다 같은 JVM 문자열 풀의 같은 객체를 반환합니다.

public class StringComparison {
    @Test
    public void StringIntern(){
        String str1 = "하이";
        String str2 = "하이";

        System.out.println(str1 == str2); // true
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.intern() == str2.intern()); // true

        String str3 = new String("하이");
        String str4 = new String("하이");

        System.out.println(str3 == str4); // false
        System.out.println(str3.equals(str4)); // true
        System.out.println(str3.intern() == str4.intern()); // true
        System.out.println(str1.intern() == str4.intern()); // true
    }
}

 


 

 

+ Recent posts