Java에서 String 비교할 때 ==과 equals() method의 차이점
== 과 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/