자바에는 기본적으로 다루는 데이터 타입이 존재한다.
- 크게 2가지로 나눠본다면 primitive(원시 데이터 타입) / non-primitive (클래스 등) 으로 나눌 수 있다.
1. 원시 데이터 타입
- boolean, byte, char, short, int, long, float, double (8개)
- 더 이상 쪼갤 수 없는 데이터로 원시 데이터 타입의 변수는 선언되면 메모리 (Stack)에 공간이 할당되며 그 공간에 실제 값이 들어가게 된다.
✔ 따라서 == 연산자로 비교하게 되면 가리키는 값을 토대로 비교하게 된다.
2. java.lang.Object 클래스를 비롯, 여기에서 파생된 다른 모든 클래스들
- 원시 데이터 타입이 아닌 클래스들은 new 키워드를 통한 인스턴스가 만들어지는 시점에 또 다른 메모리 구역 (heap)에서 새로운 공간을 할당하여 값을 저장하고 변수는 그 값이 저장된 메모리의 주소를 가리키게 된다.
✔ 따라서 == 연산자를 이용할 경우 그 메모리의 주소를 비교하게 된다.
String s1 = new String ("java");
String s2 = new String ("java");
String s3 = "java";
String s4 = "java";
- 1번처럼 new 키워드를 사용하면 그 때마다 새로운 공간을 할당하여 새로운 주소가 생긴다.
- 2번처럼 사용할 때, s3처럼 이미 같은 문자열을 생성한 적이 있다면 s4의 새로운 메모리 공간을 할당하지 않고, 새로운 변수는 기존 문자열이 저장된 메모리, String Pool(Heap)의 주소를 가리키게 된다.
실제로 해보자 (== 연산자)
✔ 따라서 s1==s2 는 false, s3==s4는 true 가 나오게 된다.
equals()
- equals 메소드는 구현에 따라 다르지만, 변수가 최종적으로 가리키고 있는 값을 기준으로 판단한다.
- 때문에 String 문자열끼리 비교할 때 == 를 사용하면 값을 가리키는 주소를 비교하게 되므로 우리가 원하는 값을 비교하고 싶다면 equals 메소드를 사용해서 비교를 해야한다.
해보자
- new 키워드를 사용해 heap 영역에 서로 다른 공간을 사용하고 있는 s1과 s2는 주소가 다르다.
때문에 주소를 비교하는 == 을 사용하면 false
- 하지만 s1과 s2는 실제 값은 java로 동일하다.
때문에 최종적으로 가리키고 있는 값을 비교하는 equals를 사용하면 true
reference!
https://www.boostcourse.org/cs128/lecture/264918?isDesc=false