동등성과 동일성

2022년 03월 02일

TOC

동일성과 동등성

동일성과 동등성은 아무생각 없이 모르고 들었을 때는 같은 말, 다른 표현이라 생각하실 수 있습니다. 하지만 프로그래밍 내에서 동일성과 동등성은 엄연하게 다른 의미를 갖고 있습니다.

일단 프로그래밍적으로 결론부터 말하면 동일하다== 이고 동등하다equals()입니다.

그럼 지금부터 각각의 차이점에 대해 알아보도록 하겠습니다.

일반적으로 우리가 숫자 변수와 같은 변수 값이 같은지를 확인하기 위해서는 == 연산자를 통해 비교를 하였습니다. 하지만 ==연산의 경우 모든 상황에서 사용가능한 것이 아닌 기본타입(Primitive type)에서만 사용가능합니다.

Primitive type -> int, float, double, short, char, boolean, byte가 있다.

기본타입 이외의 new연산을 통해 생성되는 참조 타입(Reference type)은 ==가 아닌 equals를 통해 비교를 해야합니다. 참조 타입이며 우리가 자주 사용한 String을 예시 코드로 보겠습니다.

public static void main(String[] args) {
    String string1 = new String("abc");
    String string2 = new String("abc");

    System.out.println(string1 == string2); // false
    System.out.println(string1.equals(string2)); // true
}

String 인스턴스 생성을 String string1 = "abc";가 아닌 new String()을 한 이유는 새로운 인스턴스를 생성하기 위해서입니다. 자세한 내용은 String 파헤치기 를 참조하시기 바랍니다.

위의 코드를 보면 알 수 있듯이 참조타입의 인스턴스는 같은 내용을 담았음에도 불구하고 동일성 체크인 ==로 비교를 하였을 때 false의 결과가 나왔습니다. 왜 이러한 결과가 나오는 걸까요🧐

바로 참조 타입의 자료형은 기본타입과 달리 new로 생성하며 클래스의 오브젝트를 생성하고 해당 오브젝트가 저장된 메모리의 주소를 저장하기 때문입니다. 그렇기에 참조 변수의 경우 동일성 체크인 ==를 통한 비교를 하게되면 메모리 주소값 비교를 하게되고, 서로 다른 인스턴스의 메모리 주소를 가르키는 string1과 string2는 false라는 결과를 반환하게 되는 겁니다. 즉, 정리하자면 참조 변수의 경우 동일성 체크는 인스턴스의 주소값을 비교하는 것입니다.

그렇다면 동등성 비교는 어떨까요? 참조 타입의 변수에서 동등성 체크는 동일성 체크와 다르게 주소값이 아닌 오브젝트가 같은 값을 갖고 있는지를 체크합니다. 그리하여 위의 예시코드의 동등성 체크인 equals()의 경우 true라는 결과를 반환한 것입니다.

equals 재정의

String의 경우 java에서 기본적으로 제공하는 참조타입의 자료형이기에 equals는 문자열 값이 같은지를 체크하도록 재정의 되어있습니다. 하지만 우리가 직접 만든 객체의 동등성을 비교한다면 객체 내부에 equals를 재정의해줘야 합니다. 그렇지 않을경우 객체의 최상위 클래스인 Object클래스의 equals()가 호출되어 아래와 같이 동일성 비교를 하게 됩니다.

public boolean equals(Object obj){
    return (this == obj)
}

equals() 재정의 예시는 다음과 같습니다.

public class Coffee {
  private String name;
  private int price;

  public Coffee(String name, int price) {
    this.name = name;
    this.price = price;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Coffee coffee = (Coffee) o;
    return price == coffee.price && Objects.equals(name, coffee.name);
  }

  @Override
  public int hashCode() {
    return Objects.hash(name, price);
  }
}

public static void main(String[] args) {
    Coffee coffee1 = new Coffee("americano", 4500);
    Coffee coffee2 = new Coffee("americano", 4500);

    System.out.println(coffee1.equals(coffee2));
}

정리

  • 동일성과 동등성은 엄연하게 다른 것이다.
  • 동일성은 ==을 통한 주소값 체크이며, 동등성은 equals()를 통해 오브젝트의 내부 값을 비교하는 것이다.

참조

Buy me a coffeeBuy me a coffee
Written by

@Seongwon

기술공유를 통해 새로운 가치 창조을 추구하는 백엔드 개발자 오성원입니다.
©SeongwonOh