멘토링

Java에서 String 비교할 때 ==과 equals() method의 차이점

langsamUndStetig 2022. 6. 10. 22:12

== 과 equals() 메소드 모두 두 개의 object를 비교하고 결과를 Boolean으로 반환한다.

그렇다면 무엇이 다른 건가??

 

==과 equals() 메소드의 차이점 

== equals()
연산자 메소드
힙 영역에 위치한 객체의 참조값을 비교 (address comparison)
-> 두 객체가 같은 메모리 위치를 가리키는지 체크
content comparison
객체의 값을 비교한다.

만약 equals() 메소드를 오버라이드 하지 않을 경우엔 기본적으로 equals(Object o) 메소드가 호출된다.

* 이에 관련된 것을 찾으려면  Why to Override equals(Object) and hashCode() method ? 를 보면된다.

public class Practice {
  public static void main(String[] args) {
  	//디버깅 해보니 value는 모두 같게 나왔다.
    // 객체 주소값은 찾지 못했다.
    String a = "hi"; // a.value = {byte[2]@702} [104, 105]
    String b = "hi"; // b.value = {byte[2]@702} [104, 105]
    String c = new String("hi"); // c.value = {byte[2]@702} [104, 105]

	//a와 b는 String constant Pool에 위치한 객체의 주소를 참조하고 있다.
    System.out.println(a==b); // true
    // c는 new연산자를 사용했기 때문에 Heap 영역에 위치해 있다.
    System.out.println(a==c); // false
    System.out.println(a.equals(b)); // true
    System.out.println(a.equals(c)); // true
  }
}

 

Equality operator (==)에 대해서 더 자세히 살펴보자

 

먼저 == 연산자는 모든 Boolean을 포함한 primitive type에 사용할 수 있다. 또한 Object type에도 사용이 가능하다.

만약 object type에서 사용할 경우, 동일한 유형이거나 조상-자손 관계여야 한다. 그렇지 않을 경우 compile-time error가 발생한다.

// int - int
System.out.println(3==4);  // false
// int - byte
System.out.println((byte)4 == 4); // true
// int - long
System.out.println(2000L == 2000); // true
// int - char
System.out.println(97 == 'a'); // true
// double - char
System.out.println(97.0 == 'a'); // true
// bool - bool
System.out.println(false == false); // true
System.out.println(true == false);// false
System.out.println(true == true);// true

// java: incomparable types: java.math.BigDecimal and java.lang.String
// 컴파일 시 에러가 발생한다.
BigDecimal a = new BigDecimal("2");
    String s = new String("2");
    System.out.println(a == s);

 

.equals() Method에 대해서 더 자세히 알아보자

 

자바에서 String equals() method는 주어진 두 개의 String의 값을 비교한다. 만약 값이 같다면 true, 그렇지 않다면 false를 반환한다.

 

String a = new String("hi");
String b = new String("hi");
Practice p1 = new Practice(3);
Practice p2 = new Practice(3);
Practice p3 = p1;

System.out.println(a==b); // false (주소값 비교)
System.out.println(a.equals(b)); //true (value 비교)
System.out.println(a.hashCode()); // a와 b의 hashCode()가 같다.
System.out.println(b.hashCode());
System.out.println(p1==p2); // false (주소값 비교)
System.out.println(p1==p3); // true (p1의 주소값을 p3에 할당했음)
System.out.println(p1.equals(p2)); // false (p1과 p2에 같은 값을 할당했지만 hashCode()를 overriding 하지 않아서 다르게 나온거 같음)
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
System.out.println(p1.hashCode()); //p1과 p3의 hashCode()와 주소값은 같다. 그러나 p2와는 hashCode()값도 다르다.
System.out.println(p2.hashCode());
System.out.println(p3.hashCode());
System.out.println(p1.equals(p3)); // true

* hashCode란 무엇인가??

- hashCode는 각 객체의 주소값을 변환하여 생성한 객체의 고유한 정수값으로, equals() 메소드는 이 hashCode를 비교하여 같은지 아닌지를 판단한다.

String에선 이미 value가 같으면 hashCode가 같게 나오도록 hashCode() 메소드를 overriding 되어 있었다. Object에 있는 hashCode()는 구현부가 작성되어 있지 않았다.

 

 

참고 자료

https://www.geeksforgeeks.org/difference-between-and-equals-method-in-java/