자바에서 == 연산자와 equals() 메서드의 차이점은 무엇인가요?

45 조회수
자바에서 == 연산자는 객체의 메모리 주소를 비교하고, equals() 메서드는 객체의 내용을 비교합니다. String의 경우, ==는 두 문자열 변수가 같은 메모리 위치를 참조하는지 확인하고, equals()는 문자열의 내용이 동일한지 확인합니다. 따라서 같은 값을 가진 다른 String 객체는 ==에서는 false, equals()에서는 true를 반환할 수 있습니다.
의견 0 좋아요

자바에서 == 연산자와 equals() 메서드의 차이점: 깊이 있는 이해와 활용

자바를 배우고 사용하는 개발자라면 == 연산자와 equals() 메서드의 차이점을 명확히 이해하는 것이 필수적입니다. 얼핏 보면 둘 다 '같음'을 비교하는 것처럼 보이지만, 실제 작동 방식과 비교 대상은 완전히 다릅니다. 이 둘을 혼용해서 사용하면 예상치 못한 버그를 발생시킬 수 있으므로, 각 특징과 사용 시점을 정확히 파악해야 합니다.

1. == 연산자: 주소 값을 비교하는 날카로운 칼

== 연산자는 두 피연산자의 메모리 주소 값을 비교합니다. 즉, 두 변수가 같은 메모리 공간을 가리키고 있는지 확인하는 것입니다. primitive 타입 (int, char, boolean 등)의 경우, == 연산자는 변수에 저장된 실제 값을 비교합니다. 하지만 객체 (Object) 타입의 경우, == 연산자는 객체의 내용이 아닌 객체가 저장된 메모리 주소를 비교합니다.

예를 들어, 다음과 같은 코드를 생각해 봅시다.

String str1 = new String("Hello");
String str2 = new String("Hello");

System.out.println(str1 == str2); // false

위 코드에서 str1str2는 내용이 동일한 "Hello"라는 문자열을 가지고 있지만, new String()을 사용하여 각각 새로운 객체를 생성했기 때문에 서로 다른 메모리 주소를 가집니다. 따라서 str1 == str2false를 반환합니다.

2. equals() 메서드: 내용을 비교하는 섬세한 저울

equals() 메서드는 객체의 내용을 비교합니다. Object 클래스에 정의되어 있으며, 모든 자바 객체는 이 메서드를 상속받습니다. 하지만 Object 클래스의 기본 equals() 메서드는 == 연산자와 동일하게 주소 값을 비교합니다. 따라서 객체의 내용을 비교하기 위해서는 해당 클래스에서 equals() 메서드를 재정의 (Override)해야 합니다.

String 클래스는 equals() 메서드를 재정의하여 문자열의 내용을 비교하도록 구현되어 있습니다. 따라서 위의 예시에서 다음과 같이 equals() 메서드를 사용하면 true를 얻을 수 있습니다.

String str1 = new String("Hello");
String str2 = new String("Hello");

System.out.println(str1.equals(str2)); // true

String 클래스의 equals() 메서드는 각 문자열의 문자들을 하나하나 비교하여 동일한 내용인지 확인합니다.

3. equals() 메서드 재정의의 중요성: 올바른 비교를 위한 핵심

사용자 정의 클래스에서 equals() 메서드를 재정의하지 않으면 Object 클래스의 기본 equals() 메서드가 호출되어 객체의 주소 값을 비교하게 됩니다. 따라서 논리적으로 같은 객체라도 주소 값이 다르면 equals() 메서드는 false를 반환하게 됩니다.

따라서 사용자 정의 클래스에서 객체의 내용을 기반으로 비교를 수행해야 하는 경우, 반드시 equals() 메서드를 재정의해야 합니다. equals() 메서드를 재정의할 때는 다음과 같은 규칙을 지켜야 합니다.

  • 반사성 (Reflexivity): x.equals(x)는 항상 true를 반환해야 합니다.
  • 대칭성 (Symmetry): x.equals(y)true이면 y.equals(x)true여야 합니다.
  • 추이성 (Transitivity): x.equals(y)true이고 y.equals(z)true이면 x.equals(z)true여야 합니다.
  • 일관성 (Consistency): x.equals(y)xy가 변경되지 않는 한 항상 같은 값을 반환해야 합니다.
  • null과의 비교: x.equals(null)은 항상 false를 반환해야 합니다.

equals() 메서드를 재정의할 때는 hashCode() 메서드도 함께 재정의하는 것이 좋습니다. hashCode() 메서드는 객체의 해시 코드를 반환하는 메서드이며, equals() 메서드가 true를 반환하는 두 객체는 반드시 같은 해시 코드를 가져야 합니다. 이는 HashMap이나 HashSet과 같은 자료구조에서 객체를 효율적으로 저장하고 검색하기 위해 필요한 조건입니다.

결론:

== 연산자는 객체의 주소 값을 비교하고, equals() 메서드는 객체의 내용을 비교합니다. primitive 타입의 경우 == 연산자는 실제 값을 비교합니다. 객체의 내용을 비교하기 위해서는 해당 클래스에서 equals() 메서드를 재정의해야 하며, equals() 메서드를 재정의할 때는 반드시 hashCode() 메서드도 함께 재정의하는 것이 좋습니다. 이러한 규칙들을 준수하여 올바르게 equals() 메서드를 재정의하면 객체 비교의 정확성을 높이고 예상치 못한 문제를 방지할 수 있습니다. 따라서 자바 개발자라면 == 연산자와 equals() 메서드의 차이점을 명확히 이해하고 상황에 맞게 적절히 사용하는 것이 중요합니다.