간단한 코딩테스트 문제를 풀다가 String을 == 연산자로 비교하는데, 분명히 true가 반환되어야 하는데, false가 나오는 것 같아 이상해 찾아보다가 string 의 특징에 대해 알게되어 정리해 보려고 한다.
== 은 주소값을 비교하는 특징이 있다. 즉, 두 인스턴스가 있다면 이를 비교할 때 주소값을 비교한다는 의미이다. call by value 방식을 사용하는 primitive type은 ==을 사용해도 상관이 없지만, call by reference방식인 객체들은 주소값을 가지기 때문에 주소값이 다르다면 서로 비교할 때 false가 반환된다. String또한 클래스이기 때문에 ==로 비교하면 안되는 것이다.
String a = "hi";
String b = "hi";
위와 같이 리터럴 방식을 사용하면 a 변수가 "hi"를 가지면서 String pool에 "hi"가 저장되는데, b = "hi"이도 리터럴 방식이면 String pool에 같은 "hi"를 바라보기 때문에 둘의 주소값과 값 모두 같다.
String a = "hi";
String b = new String("hi");
그러나 위와 같이 string의 인스턴스를 생성하면 heap영역에 저장되기 때문에 주소값을 가지게 된다. b는 string pool이 아닌 heap영역에 저장되어 둘을 ==로 비교하면 false를 반환하게 된다. 그래서 문자열을 비교해줄 때문 equals()를 사용하는 것이다.
equals() 는 값자체를 비교하는 특징이 있다. 즉 주소값을 비교하는 것이 아닌 값 자체가 같은지를 비교하는 것이다.
String a = "hi";
String b = new String("hi");
a.equals(b); //true
equals()는 값 자체를 비교하기 때문에 주소값이 달라도 값이 같다면 true가 반환된다.
String a = "안녕";
String b = "안녕";
String c = new String("안녕");
if(a == b){} //true : string pool에 존재하기 때문에
if(a.equals(b)){} //true : 값이 같기 때문에
if(a == c){} // false : 위 둘의 주소값이 다르기 때문에
if(a.equals(c)){} //true : 둘의 값이 같기 때문에