본 글은 2021년 12월 14일 에 기록되었다.
본 내용은 다음의 두 유형의 사람들을 전제로 하고 있다.
특히 2번을 아는 사람이라면 Object 클래스의 몇몇 메서드를 오버라이드 해본 경험이 있을 것이라고 생각한다. toString 과 같은 메서드. 그런 사람이라면 더욱 이 내용을 추천한다.
Object 에 있는 메서드 중 final 이 있는 메서드들은 모두 재정의를 가정하고 만들어졌고 그 항목은 다음과 같다.
이 메서드들은 일반 규약 에 맞게 재정의하여 사용해야 한다.
말로하면 생각보다 어렵지만 코드로 적으면 생각보다 쉽다.
한 번 읽어보고 따라하면 바로 이해할 수 있을 것이라고 생각한다.
원제목 | equals 는 일반규약을 지켜 재정의하라
Object 명세에 적힌 일반규약은 다음과 같다.
용어 정리
String A="안녕하세요";
String B="반갑습니다.";
System.out.print(A==B); // false
System.out.print(A.eqauls(B)); // true
equals 메서드 구현 방법(단계적)
equals 메서드 구현 주의사항
원제목 | equals 를 재정의하려거든 hashCode 도 재정의하라
Object 명세에 적힌 일반규약은 다음과 같다.
용어정리
hashCode 메서드 구현방법(단계적)
int 타입 변수 result를 선언한 후 값 c로 초기화 한다.
이 때, c는 객체의 첫번째 핵심필드를 단계 2.a 방식으로 계산한 해시코드이다.
해당 객체의 나머지 핵심필드 f 각각에 대해 다음의 작업을 수행한다.
2.a. 해당 필드의 해시코드 c를 계산한다.
2.a.1. 기본 타입 필드라면 Type.hashCode(f) 를 실행한다.'
2.a.2. 참조 타입 필드면서 이 클래스의 equals() 가 이 필드의 equals() 를 재귀적으로 호출해 비교한다면, 이 필드의 hashCode 를 재귀적으로 호출한다.
+만약, 게산이 복잡해질 것 같으면 이 필드의 표준형을 만들어 그 표준형의 hashCode를 호출한다. 필드의 값이 null 이면 0을 사용한다.
2.a.3. 필드가 배열이라면 핵심 원소 각각을 별도 필드처럼 다룬다.
이상의 규칙을 재귀적으로 적용해 각 핵심 원소의 해시코드를 계산한 다음 단계 2.b 방법으로 갱신한다. 모든 원소가 핵심원소라면 Arrays.hashCode 를 사용한다.
2.b. 단계 2.a 에서 계산한 해시코드 c 로 result 를 갱신한다.
**result=31*result+c;
result 를 반환한다.
// 클래스 중요 필드 lineNum,prefix,areaCode
@Override public int hashCode() {
int result=Short.hashCode(areaCode);
result=31*result+Short.hashCode(prefix);
result=31*result+Short.hashCode(lineNum);
return result;
}
hashCode 메서드 주의사항
hashCode 쉽게하기
// 클래스 중요 필드 lineNum,prefix,areaCode
@Override public int hashCode() {
return Objects.hash(lineNum,prefix,areaCode);
}
hashCode 의 충돌 횟수를 줄이기
[Guava] com.google.common.hash.Hashing 을 참고하자.
원제목 | toString 을 항상 재정의하라.
toString 재정의의 본질
toString 을 재정의 하는 이유는 어떤 객체에 대한 테스트 검증 절차를 쉽게 하기 위함이다.
사용자 정의 클래스 PhoneNumber 를 정의해놓고 이를 출력해보면 주소값이 나올 뿐이다.
이는 직관적이지도 않을 뿐더러 본질의 목적에 맞지 않는다.
toString 은 객체의 정보를 보여줄 수 있어야 한다.
단, 객체의 필드가 너무 많다면 핵심 필드 혹은 요약 정보를 보여줘도 된다.
toString 재정의 하지 않아도 되는 케이스
Static Utiltiy Class 는 toString 을 제공할 이유가 없다
또한 대부분의 Enum 또한 toString 을 제공할 이유가 없다.
원제목 | clone 재정의는 주의해서 진행하라
본 내용은 Cloneable 인터페이스와 Reflextion 에 대해서 다루고 있고
이는 각각 아이템 20, 아이템 65 의 내용을 어느 정도 알아야 한다고 생각한다.
하지만 작성일 시점인 2021년 12월 14일 에는 이 부분을 공부하지 않았기에 스킵하도록 하였다.
해당 부분에 대한 학습이 필요하다는 판단이 서면, 이를 진행하고 포스트를 보완하도록 하겠다.
원제목 | comparable 을 구현할지 고민하라
Object.equals vs Comparable.compareTo
본 내용은 Comparable 인퍼테이스의 유일무이한 메서드인 compareTo 를 다루고 있다.
Object 클래스의 메서드인 equals 와는 두 가지만 제외하고 성격적으로 동일하다.
그 차이점은 아래와 같다.
compareTo 오버라이드 이점
compareTo 오버라이드 안할 경우 단점
Object 명세에 적힌 일반규약은 다음과 같다.
여기서부터는 compareTo 메서드에 대한 이해가 필요하다.
하지만 작성일 시점인 2021년 12월 14일 에는 이 부분을 공부하지 않았기에 스킵하도록 하였다.
해당 부분에 대한 학습이 필요하다는 판단이 서면, 이를 진행하고 포스트를 보완하도록 하겠다.