개발을 하다보면 인스턴스 필드들만 모아놓는 목적만 가진 아래와 같은 클래스를 구성하는 경우가 있다. class Point { public double x; public double y; } 이러한 클래스 형태로 구현하였을 때는 클라이언트에서 필드에 직접 접근할 수 있으므로 캡슐화의 이점을 제공하지 못한다. 그리고 또 다른 단점들은 API를 수정하지 않고는 내부 표현을 바꿀 수 없다. public 필드로만 구성되어 있기 때문에 내부 표현을 변경하기 위해서는 필드를 변경해야 한다. 불변식을 보장할 수 없다. 클라이언트에서 직접적으로 필드에 접근하고 있으므로 클라이언트에 의해 언제든지 변경이 가능하다. 외부에서 필드에 접근 할 때 부수적인 로직을 추가할 수 없다. Point.x 라는 필드를 조회했을 때 부수적..
Object의 기본 toString은 클래스이름@16진수 해시코드를 반환하여 그다지 쓸모 없는 메시지를 출력하게 된다. toString을 재정의 하면 훨씬 보기 편하게 만들 수 있다. 그리고 toString을 직접 호출하지 않아도 다른 어딘가에서 많이 호출하기 때문에 정의해두면 좋다. 실전에서 toString은 그 객체가 가진 주요 정보를 모두 반환하는게 좋다. @Override public String toString() { return "PhoneNumber{" + "ariaCode=" + ariaCode + '}'; } 예외적으로 대부분의 열거 타입은 자바가 이미 완벽한 toString을 제공하므로 따로 재정의할 필요가 없다. 그러나 하위 클래스들이 공유할 문자열 표현이 있는 추상클래..
equals를 재정의한 클래스는 hashCode도 재정의 해야 한다. 그렇지 않으면 인스턴스를 HashMap이나 HashSet 같은 컬렉션의 원소로 사용할 때 문제가 발생한다. hashCode 일반 규약 equals 비교에 사용되는 정보가 변경되지 않았다면, hashCode도 변하면 안된다. equals가 두 객체가 같다고 판단했다면, 두 객체의 hashCode는 똑같은 값을 반환한다. equals가 두 객체를 다르다고 판단했더라도, hashCode는 꼭 다를 필요는 없다. 논리적으로 같은 객체는 같은 해시코드를 반환해야 한다. equals가 물리적으로 다른 두 객체를 논리적으로 같다고 할 때, hashCode는 서로 다른 값을 반환하다. Map map = new HashMap(); map.put(new..
equals는 재정의하기 쉬워보이지만 곳곳에 함정이 있다. 문제를 회피하는 가장 쉬운 길은 아예 재정의하지 않는 것이다. 그러니 다음에 해당된다면 재정의하지 않는것이 좋다. equals를 재정의 하면 안되는 경우 각 인스턴스가 본질적으로 고유할 때 값 클래스(Integer, String)가 아닌 동작하는 개체를 표현하는 클래스 ex) Thread 인스턴스의 '논리적 동치성'을 검사할 일이 없을 때 객체값 비교가 아니라 객체 안에 값을 검사할 일이 없을 경우 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞을 때 Set은 AbstractSet이 구현한 equals를 상속, List는 AbstractList, Map은 AbstractMap 클래스가 private이나 package-privat..