본문 바로가기
Language/Java

[JAVA] equals()와 == 연산자의 결정적 차이 : 메모리 주소와 논리적 동등성

by Papa Martino V 2026. 1. 16.
728x90

equals()와 == 연산자의 결정적 차이
equals()와 == 연산자의 결정적 차이

 

자바 프로그래밍을 시작할 때 가장 먼저 마주하는 혼란 중 하나는 "두 객체가 같다"는 정의입니다. 일상 언어에서는 '같다'라는 표현이 하나지만, 자바의 세계에서는 이것이 메모리상의 위치를 의미하는지, 아니면 객체가 담고 있는 내용을 의미하는지에 따라 완전히 다른 도구를 사용해야 합니다. 이 글에서는 실무에서 흔히 발생하는 논리 오류를 방지하기 위해 == 연산자와 equals() 메서드의 내부 동작 원리를 심층적으로 분석합니다.

 

--- ## 1. 비교의 시작: 동일성(Identity) vs 동등성(Equality) 자바에서 비교를 이해하기 위해서는 먼저 두 가지 개념을 명확히 구분해야 합니다.

  • 동일성 (Identity): 두 객체가 메모리 공간에서 같은 주소를 가리키고 있는 상태 (완전히 같은 존재).
  • 동등성 (Equality): 두 객체가 메모리 주소는 다르더라도, 그 내부의 데이터(값)가 서로 같은 상태 (쌍둥이 같은 존재).

### == 연산자 (Comparison Operator) == 연산자는 비교하고자 하는 두 대상의 메모리 주소값을 비교합니다.

  • 기본 타입(Primitive Type: int, boolean 등)의 경우 변수에 실제 값이 저장되므로 값을 직접 비교합니다.
  • 참조 타입(Reference Type: String, Object 등)의 경우 힙(Heap) 영역에 있는 객체의 주소를 비교합니다.

### equals() 메서드 (Method) equals()는 모든 자바 객체의 조상인 Object 클래스에 정의된 메서드입니다. 기본적으로는 == 연산자와 동일하게 주소값을 비교하지만, 내용물(데이터)을 비교하도록 재정의(Overriding)하여 사용할 수 있다는 점이 핵심입니다. --- ## 2. String 클래스로 보는 차이점 자바에서 String은 일반적인 객체와 다르게 'String Constant Pool'이라는 특별한 메모리 관리 방식을 가집니다. 이를 통해 두 연산자의 차이를 명확히 볼 수 있습니다.


String str1 = "Java";
String str2 = "Java";
String str3 = new String("Java");

System.out.println(str1 == str2);      // true (같은 리터럴이므로 Constant Pool 공유)
System.out.println(str1 == str3);      // false (new 키워드로 새로운 힙 메모리 할당)
System.out.println(str1.equals(str3)); // true (내용인 "Java"는 동일함)

 

--- ## 3. 요약 및 비교 분석 아래 표는 == 연산자와 equals() 메서드의 핵심 차이점을 한눈에 파악할 수 있도록 정리한 내용입니다.

구분 == 연산자 equals() 메서드
비교 유형 동일성(Identity) 비교 동등성(Equality) 비교
비교 대상 메모리 주소 (Address) 객체의 내용 (Content)
사용 가능 타입 기본 타입 & 참조 타입 모두 가능 참조 타입(객체)만 가능
재정의 여부 변경 불가능 개발자가 오버라이딩 가능
Null 처리 Null 비교 시 true/false 반환 Null 객체 호출 시 NullPointerException 발생

 

--- ## 4. 개발 시 주의사항: equals를 재정의할 때의 규칙 객체의 동등성을 정의하기 위해 equals()를 재정의한다면, 반드시 hashCode()도 함께 재정의해야 합니다. 이는 Hash 기반 컬렉션(HashSet, HashMap, HashTable)에서 객체를 올바르게 식별하기 위한 자바의 규약입니다. > 참고: equals()가 true를 반환하는 두 객체는 반드시 같은 hashCode()를 가져야 합니다. 하지만 그 역은 항상 성립하지 않습니다. --- ## 5. 결론: 언제 무엇을 써야 할까? 자바 개발에서 실수를 줄이기 위한 골든 룰은 다음과 같습니다.

  1. int, char, boolean 같은 기본 자료형의 값을 비교할 때는 ==를 사용하세요.
  2. String을 포함한 모든 객체의 '내용'이 같은지 확인할 때는 반드시 equals()를 사용하세요.
  3. 객체의 equals()를 호출할 때는 변수가 null인지 먼저 체크하거나, Objects.equals(a, b)를 활용하여 안정성을 높이세요.

이 원칙만 지켜도 런타임에 발생하는 원인 모를 로직 버그의 90% 이상을 사전에 방지할 수 있습니다.

 

[출처 및 참고 자료]
1. Oracle Java Documentation - Object Class
2. Effective Java 3rd Edition (Joshua Bloch)
3. Java Language Specification - Comparison Operators

728x90