[JAVA] 문자열 비교[== vs equals()]의 차이

자바에서 기본 자료형(원시타입)의 비교 연산은 일반적으로 == 연산자를 사용합니다. 하지만 String의 경우는 == 연산자를 사용하여 비교하면 안전하지 않죠? 안전하지 않다는 말은 무슨 뜻일까요?


String의 경우 여러분들이 편하게 아무생각(?) 없이 사용하는 리터럴 즉, 대입 연산자를 이용해 바로 상수를 대입하는 방식으로 사용할 경우에는 일반적으로 == 를 이용해 값을 확인해도 문제가 없습니다. 하지만 사용자로 부터 입력을 받아 사용할 경우 동일한 값을 입력 받더라도 비교 연산자(==)는 동일한 값인데도 false를 반환하죠.


즉 아래와 같이 코드를 작성했다고 가정합시다. 


Scanner sc = new Scanner(System.in);
String id = sc.next();			    // 사용자한테 ‘abc’를 입력 받았다고 가정.
System.out.println(id == “abc”);	// 비교연산자(==)를 이용해 비교하면 false.

// 그래서 우리는 String의 메소드인 equals()를 이용해 비교하면 true를 반환합니다.
System.out.println(id.equals("abc"));



이처럼 비교연산자(==)와 equals()는 왜 차이가 나는 것인지 한번 살펴보기로 하겠습니다. 먼저 그림을 보도록 하겠습니다.



위 그림에 대한 결론부터 이야기 하자면 String과 같은 클래스에서의 비교연산자(==)는 객체의 주소을 비교하는 것이고, equals()는 주소가 가리키는 실제의 값, 즉 문자열을 비교하는 메소드입니다. 따라서 우리는 String를 사용할 때 항상 안전하게 그리고 생각하지 말고 equals()를 사용하라고 배우죠.


위의 그림에서 선언한 각각의 변수들 주소를 이클립스에서 출력해보면 다음과 같습니다.


String str1 = "Hello";
String str2 = "Hello";

String str3 = new String("World");
String str4 = new String("World");
		
System.out.printf("str1 address : 0x%X\n", System.identityHashCode(str1));
System.out.printf("str2 address : 0x%X\n", System.identityHashCode(str2));
System.out.printf("str3 address : 0x%X\n", System.identityHashCode(str3));
System.out.printf("str4 address : 0x%X\n", System.identityHashCode(str4));



자바에서 클래스 객체의 메모리 주소를 출력해주는 메소드는 System.identityHashCode()를 이용하면됩니다. 그리고 좀더 메모리 주소 같이 보이도록 printf(%X) 16진수 포맷을 이용했습니다.


str1 address : 0x626B2D4A
str2 address : 0x626B2D4A
str3 address : 0x3339AD8E
str4 address : 0x555590


위 결과를 살펴보면 str1, str2는 주소가 동일하고 str3, str4는 주소가 틀리죠. 이와같이 new 연산자를 이용할 경우 동일한 값일지라도 항상 새로운 주소의 객체를 생성합니다. 또한 Scanner 클래스의 next() 메소드를 이용하여 값을 받아올 경우도 내부적으로는 String 객체를 생성하여 이 값을 반환하는 것이기 때문에 주소가 달라지는 것이죠.


그렇기에 결론적으로 String에서는 비교연산자 == 사용을 자제하고 안전하게 equals()를 사용하라고 말을 합니다.


위의 결과에서 보는 바와 같이 우리가 변수에서 기본타입(원시타입) 변수인 int, double, char 등과 참조타입 변수인 String을 구분 짓는 가장 큰 이유 중 하나가 바로 이렇게 메모리에 값을 바로 갖느냐 아니면 메모리 주소를 참조하여 값을 갖느냐 인 것이죠.


댓글

이 블로그의 인기 게시물

[JAVA] 변수란? 변수타입?

[JAVA] 문자셋(Charset)