2016년 11월 4일 금요일

[자바] Effective Java 3장 - 모든 객체의 공통 메서드

모든 객체의 공통 메서드

1. equals를 재정의할 때는 일반 규약을 따른다.

  • equals() : 주어진 객체를 비교하여 그 객체가 같은지 여부를 반환하는 메서드
  • 가장 확실한 방법은 equals() 메서드를 재정의하지 않는 것이다. 이 경우, 그 클래스의 객체는 유일한 객체가 된다.
  • equals() 메서드를 안써도 되는 조건(하나라도 만족한다면 재정의할 필요 없다.)
    • 각각의 객체가 고유하다.
    • 클래스에 논리적 동일성 검사방법이 있든지 없든지 상관없다.
    • 상위 클래스의 equals()를 하위 클래스에서도 잘 사용할 수 있다.
  • equals()메서드를 재정의할 필요가 있는 조건
    • 논리적 동일성을 지원해야 할 때(ex 문자열객체 비교)
    • 상위 클래스의 equals()가 하위 클래스에 맞지 않을 때
  • 대부분의 자바 API 클래스는 equals() 메서드가 재정의되어 있다고 가정하고 구현되어 있다.
  • equals()메서드를 재정의하기 위해 점검해야 할 규칙
1. == 연산자를 사용하여 equals()의 인자가 자기 자신인지 검사한다.
2. instanceof 연산자를 이용해 인자의 자료형이 정확한지 검사한다.
3. 2에서 검사한 인자를 정확한 자료형으로 변환한 후에 검사를 진행한다.
4. 현재 객체와 비교하고자 하는 객체의 필드 각각이 일치하는지 검사한다.(중요)
5. equals() 메서드를 구현할 때, hashCode()도 재정의하여 구현한다.

2. equals를 재정의할 때는 반드시 hashCode도 재정의한다.

  • hashCode() : 객체를 구분하는 해쉬값을 반환하는 메서드
  • equals() 메서드가 같다고 판정한 두 객체의 hashCode() 값은 반드시 같아야 한다.
    • equals() 메서드를 구현하고, hashCode() 메서드를 구현하지 않으면 자바의 해쉬기반 API에서 오동작을 일으키게 된다.
  • 해쉬함수를 만들 때, equals() 메서드에서 비교를 위해 사용된 필드를 이용하도록 한다. 그래야 같은 필드값일 때 해쉬값이 똑같이 나오게 된다.
  • hashCode()메서드를 재정의하기 위한 규약
1. 프로그램이 실행중일 때, 같은 객체의 hashCode메서드를 여러 번 호출하는 경우 언제나 동일 결과가 나와야 한다.(종료되었다가 재시작될 때에는 다른 값이 나와도 된다.)
2. equals 메서드가 같다고 판단한 두 객체의 hashCode메서드 결과는 같아야 한다.
3. equals 메서드가 다르다고 판단한 두 객체의 hashCode메서드 결과는 같아도 되고 달라도 되지만, 다를경우 해시테이블의 성능이 향상된다는 것을 기억한다.

3. toString은 항상 재정의한다.

  • toString() : 주어진 객체를 문자열로 반환하는 메서드.
  • Object.toString() 메서드는 "클래스명@해시코드" 형태이므로 유용하지 않다.
  • toString()메서드는 제약,규약이 존재하지 않지만, 잘 정의한 메서드는 클래스를 좀 더 유용하게 이용하도록 도와준다.
    • 객체 내의 중요 정보(필드)를 모두 담아 반환
    • 문자열의 내용을 하눈에 파악할 수 있도록
    • toString()메서드에서 제공하는 정보를 파싱용으로 이용하면 안되므로, 제공하는 모든 정보는 프로그래밍적으로 가져올 수 있도록 제공한다.

4. clone을 재정의할 때는 신중하게 한다.

  • clone() : 객체를 복사하여 반환하는 메서드. Cloneable인터페이스를 구현하지 않으면 CloneNotSupportedException을 던진다.
  • clone()메서드를 재정의하기 위한 규약
1. final 이 아닌 클래스에서 재정의할 때는 반드시 super.clone()을 호출해 얻은 객체를 반환해야 한다.
2. clone()을 구현할 때 원래 객체를 손상시키지 않도록 하고, 복사본의 불변식도 제대로 만족시켜야 한다.
3. 객체복사를 굳이 제공해야 한다면, clone()메서드 보다는 복사생성자 or 팩터리 메서드를 제공하는 방안을 검토한다.

5. Comparable 구현을 고려한다.

  • compareTo() : equals() 메서드와 비슷하게, 두 객체를 비교하여 순서를 반환하는 메서드이다. 이 메서드는 Comparable 인터페이스 내부에 존재한다.
  • 시스템에서 제공하는 정렬, 검색 등의 편의성 메서드들은 내부적으로 모두 compareTo() 메서드를 이용한다. 그러므로, 객체간의 순서가 중요한 클래스는 가급적 구현하는 것이 좋다.
  • compareTo() 메서드를 재정의하기 위한 규약
1. 객체간 비교순서를 바꿔도 객체간의 대소관계는 그대로 유지되어야 한다.
2. compareTo를 이용한 동치 검사 결과는 일반적으로 equals 메서드 실행 결과와 같아야 한다.

댓글 없음:

댓글 쓰기