이펙티브 코틀린 아이템 40: equals 의 규약을 지켜라

이펙티브 코틀린(클래스설계)

아이템 40: equals 의 규약을 지켜라

동등성

코틀린에는 두 가지 종류의 동등성(equality)이 있다.

  • 구조적 동등성(structural equality) : equals 메서드와 이를 기반으로 만들어진 == 연산자(!= 포함)로 확인하는 동등성이다.
  • 레퍼런스적 동등성(referential equality**) : === 연산자(!== 포함)로 확인하는 동등성이다.

equals 는 모든 클래스의 슈퍼클래스인 Any 에 구현되어 있으므로, 모든 객체에서 사용할 수 있다.
다만, 연산자를 사용해서 다른 타입의 두 객체를 비교하는 것은 허용되지 않는다.

“”.equals(1) 은 가능하지만, “” == 1 은 불가능하다.

같은 타입을 비교하거나, 둘이 상속 관계를 갖는 경우에는 비교할 수 있다.

equals 가 필요한 이유

Any 클래스에 구현되어 있는 equals 메서드는 디폴트로 === 처럼 두 인스턴스가 완전히 같은 객체인지를 비교한다.

이는 모든 객체는 디폴트로 유일한 객체라는 것을 의미한다.

data 한정자를 붙여서 데이터 클래스로 정의하면, 두 객체가 기본 생성자와 프로퍼티가 같다면 동등성으로 동작한다.

모든 프로퍼티가 아닌 일부 프로퍼티로만 동등성을 비교 할때는 데이터 클래스에서 동등성 비교 대상이 아닌 프로퍼티를 생성자 프로퍼티가 아닌 클래스 프로퍼티로 선언하면 된다.

기본 생성자에 선언되지 않은 프로퍼티는 copy() 메서드로 복사되지 않는다.

equals 를 직접 구현해야 하는 경우

  • 기본적으로 제공되는 동작과 다른 동작을 해야 하는 경우
  • 일부 프로퍼티만으로 비교해야 하는 경우
  • data 한정자를 붙이는 것을 원하지 않거나, 비교해야 하는 프로퍼티가 기본 생성자에 없는 경우

equals 구현하기

  • 특별한 이유가 없는 이상, 직접 equals 를 구현하는 것은 좋지 않다.
  • 만약 상속을 한다면, 서브클래스에서 equals 가 작동하는 방식을 변경하면 안 된다는 것을 기억하자.

참조