날이면 날마다 헷갈리는 eqauls()와 ==의 차이..
다시는 헷갈리지 않기 위해 정리 한 번 하고 간다
자바에서는 String 타입을 비교하기 위해 equals()와 == 두 가지 연산자를 사용한다.
결론부터 말하자면 둘의 차이점은 '내용을 비교하는가' vs '주소를 비교하는가' 이다.
자세하게 살펴보기 위해 먼저 Java에서 String 객체의 생성 방법을 먼저 살펴보아야 한다.
자바 String객체 생성 : String str=""와 String str = new String("")의 차이
자바에서 String 객체를 생성하는 방법은 두 가지이다.
String str=""
와 String str = new String("")
이 둘의 차이점은 무엇일까?
자바에서 String 객체는 Immutable Class(불변 클래스)이자 Reference Type(참조 객체)이다.
첫 번째 방법인 String str=""
를 통해 String 객체를 생성할 경우, String Pool에 같은 값이 있는지 확인하고 있으면 그 주소값을 리턴하고 없을 경우 새로운 객체를 생성하여 String Pool에 저장한다.
String str1 = "sujinhope";
String str2 = "sujinhope";
// hash code 비교(동일한 객체인지)
System.out.println("str1 hashCode : " + System.identityHashCode(str1));
System.out.println("str2 hashCode : " + System.identityHashCode(str2));
위의 예제를 보면 str1과 str2를 동일한 내용으로 객체를 선언했을 때 해시코드 값이 같다는 것(==동일한 객체임)을 확인할 수 있다.
반면, String str = new String("")을 이용하여 객체를 생성할 경우 내용이 같더라도 매번 새롭게 객체를 생성하여 저장한다.
String newStr1 = new String("sujinhope");
String newStr2 = new String("sujinhope");
System.out.println("newStr1 hashCode : " + System.identityHashCode(newStr1));
System.out.println("newStr2 hashCode : " + System.identityHashCode(newStr2));
첫 번째 예제와 동일하게 같은 내용으로 객체를 생성하였음에도 두 객체의 해시코드값이 다름을 확인할 수 있다.
메모리에 저장되는 방식도 다른데, 리터럴로 생성할 경우 객체는 Heap 메모리 내의 별도 공간인 String Constant Pool이라는 곳에 저장된다. 반면, new 연산자를 이용할 경우 각 객체는 String Pool이 아닌 그냥 Heap 메모리 내에 생성된다.
그래서, equals()와 ==의 차이점은?
결론으로 돌아와서, equals() 연산은 객체의 내용을 비교한다.
==으로 비교할 경우 객체의 주소값을 비교한다. 즉, 두 객체가 같은 객체인지 비교하는 연산이다.
앞선 예제를 활용하여 equals()와 ==의 차이를 비교해보자.
String str1 = "sujinhope";
String str2 = "sujinhope";
String newStr = new String("sujinhope");
// 해시코드
System.out.println("\n해시코드 비교");
System.out.println(System.identityHashCode(str1)); // 914424520
System.out.println(System.identityHashCode(str2)); // 914424520
System.out.println(System.identityHashCode(newStr)); // 110718392
// 비교 연산
System.out.println("\n비교 연산자");
// 내용을 비교
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(newStr)); // true
// 주소값을 비교
System.out.println(str1 == str2); // true
System.out.println(str1 == newStr); // false
동일한 내용으로 String 객체를 생성하였을 때 str1과 str2는 동일한 객체를 참조하므로 해시코드 값이 동일하다. 반면 new 연산자로 생성한 newStr은 별도의 객체로 생성된 것을 볼 수 있다.
비교 연산자로 비교해보았을 때 .equals()
의 경우 내용을 비교하기 때문에 str1, str2, newStr이 모두 동일하다고 판단하지만 ==
의 경우 주소값을 비교하기 때문에 str1과 newStr이 다르다고 판단한다.
'백엔드' 카테고리의 다른 글
[Java/Postgresql] 랜덤 문자열 생성 - get_random_string() (0) | 2022.03.21 |
---|---|
[Spring] Spring MVC 구조 - Dispatcher Servlet 이란? (0) | 2022.02.04 |
[Java] Generic이란? Generic class Class field 가져오기, 동적 메소드 실행 (0) | 2021.10.01 |
[Spring] IoC와 DI - 2. IoC(제어의 역전)이란? (토비의 스프링) (0) | 2021.09.26 |
[Spring] Bean Factory와 Application Context (0) | 2021.09.25 |
댓글