Java에서는 int와 boolean과 같은 일반적인 데이터 타입의 비교는 == 연산자를 사용하여 비교한다. 하지만 String과 같은 Class 값의 비교는 equals() 메소드를 사용하여 비교한다.
이때, equal와 ==의 차이점을 알아보자.
== 연산자는 비교하고자 하는 두 대상의 주소값을 비교해주는 반면에, equals 메소드는 비교하고자 하는 두 대상의 값 자체를 비교해준다.
int, char 형과 같은 기본 타입들은 Call by Value 형태로 기본적으로 대상에 주소값을 가지지 않는다. 하지만 String은 일반적인 타입이 아닌 클래스이다. 클래스는 Call by Reference 형태로 생성하는 즉시 바로 주소값이 부여된다.
따라서 String 타입을 선언했을 경우, 같은 값을 지니더라도 주소값은 엄연히 다른 값이다.
String 변수를 생성할 때에는 두가지 방법이 존재한다.
1. 리터럴을 이용한 방식
2. new 연산자를 이용한 방식
두 방식의 차이점을 알아보자.
리터럴을 사용할 경우, string constant pool이라는 영역에 존재하게 된다.
new 연산자를 사용하여 String을 생성할 경우, Heap 영역에 존재하게 된다.
String을 리터럴로 선언할 경우, 내부적으로 String의 intern() 메서드가 호출된다.
intern() 메서드는 주어진 문자열이 string constant pool 영역에 존재하는지 검색하여 값이 존재하면 그 값의 주소값을 반환하고 존재하지 않으면 string constatnt pool 영역에 값을 추가하여 새로운 주소값을 반환한다.
String s1 = "str";
String s2 = new String("str");
System.out.println(s1 == s2 ); // false
System.out.println(s1.equals(s2)); // true
위 코드를 보면 첫번째 결과값은 false가 출력된다. == 연산자는 주소값을 비교해주기 때문에 같은 "str" 값을 가져도 s1과 s2가 다르다는 결론이 나온다.
두번재 결과값은 true가 출력된다. equals 메소드는 주소값이 아닌 데이터 그 자체의 값을 비교하기 때문에 s1과 s2의 값 모두 "str"을 지니고 있어서 같다는 결론이 나온다.