본문 바로가기
백엔드

[Java] equals()와 ==의 차이점(feat: String str=""와 new String("")의 차이점)

by BeforB 2022. 2. 3.
728x90

날이면 날마다 헷갈리는 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));

String str = ""로 객체 생성

위의 예제를 보면 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));

String str = new String("")으로 객체 생성

 

첫 번째 예제와 동일하게 같은 내용으로 객체를 생성하였음에도 두 객체의 해시코드값이 다름을 확인할 수 있다.

 

 

 

메모리에 저장되는 방식도 다른데, 리터럴로 생성할 경우 객체는 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이 다르다고 판단한다.

 

 

 

 

 

 

728x90

댓글