본문 바로가기
728x90

Books/Effective-Java 3판18

15. 클래스와 맴버의 접근 권한을 최소화하라 어설프게 설계된 컴포넌트와 잘 설계된 컴포넌트의 가장 큰 차이는 바로 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 얼마나 잘 숨겼느냐다 - 잘 설계된 컴포넌트는 모든 내부 구현을 완벽히 숨겨, 구현과 API를 깔끔히 분리한다 - 오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 동작 방식에는 전혀 개의치 않는다. - 정보 은닉, 혹은 캡슐화라고 하는 이 개념은 소프트웨어 설계의 근간이 되는 원리다. 정보 은닉의 장점은 정말 많다 그중 대부분은 시스템을 구성하는 컴포넌트들을 서로 독립시켜서 개발, 테스트, 최적화 적용, 분석, 수정을 개별적으로 할수 있게 해주는것과 연관 되어 있다 * 시스템 개발 속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문이다 * 시스템 관리 비용.. 2021. 10. 11.
14. Comparable을 구현할지 고려하라 이번에는 Comparable 인터페이스의 유일무이한 메서드인 compareTo를 알아보자 - compareTo는 Object의 메서드가 아니다 - 성격은 두 가지만 빼면 Object의 equals와 같다 - compareTO는 단순 동치성 비교에 더해 순서까지 비교할 수 있으며, 제네릭하다 - Comparable을 구현했다는 것은 그 클래스의 인스턴스들에는 자연적인 순서가 있음을 뜻한다 - Comparable을 구현한 객체들의 배열은 다음처럼 손쉽게 정렬할 수 있다. Arrays.sort(a); 검색, 극단값 계산, 자동 정렬되는 컬렉션 관리도 역시 쉽게 할 수 있다 public class WordList{ public static void main(String[] args){ Set s = new Tr.. 2021. 10. 10.
13. clone 재정의는 주의해서 진행하라(2) 코드 13-3 잘못된 clone 메서드 - 가변 상태를 공유한다! // 코드 13-1 가변 상태를 참조하지 않는 클래스용 clone 메서드 (79쪽) @Override public PhoneNumber clone() { try { return (PhoneNumber) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(); // 일어날 수 없는 일이다. } } - 복제본은 자신만의 버킷 배열을 갖지만, 이 배열은 원본과 같은 연결 리스트를 참조하여 - 원본과 복제본 모두 예기치 않게 동작할 가능성이 생긴다 - 이를 해결하려면 각 버킷을 구성하는 연결 리스트를 복사해야 한다 코드 13-4 복잡한 가변 상태를 갖는 .. 2021. 10. 6.
13. clone 재정의는 주의해서 진행하라(1) 메서드 하나 없는 Cloneable 인터페이스는 대체 무슨 일을 할까? - Object의 protected 메서드인 clone의 동작 방식을 결정한다 - Cloneable을 구현한 클래스의 인스턴스에서 clone을 호출하면 그 객체의 필드들을 하나하나 복사한 객체를 반환하며, - 그렇지 않은 클래스의 인스턴스에서 호출하면 CloneNotSupportedException을 던진다 - 인터페이스를 상당히 이례적으로 사용한 예이니 따라하지는 말자 인터페이스를 구현한다는 것은 일반적으로 해당 클래스가 그 인터페이스에서 정의한 기능을 제공한다고 선언하는 행위 - 그런데 Cloneable의 경우에는 상위 클래스에 정의된 protected 메서드의 동작 방식을 변경한 것이다. 실무에서는 Cloneable을 구현한 클.. 2021. 10. 5.
12. toString을 항상 재정의하라 Object의 기본 toString 메서드가 우리가 작성한 클래스에 적합한 문자열을 반환하는 경우는 거의 없다 - 단순히 클래스_이름@16진수로 표시한_해시 코드를 반환 - toString의 일반 규약에 따르면 '간결하면서 사람이 읽기 쉬운 형태의 유익한정보' 를 반환한다 - toString의 규약은 "모든 하위 클래스에서 이 메서드를 재정의 한다" toString을 잘 구현한 클래스는 사용하기에 훨씬 즐겁고, 그 클래스를 사용한 시스템은 디버깅이 쉽다 - toString 메서드는 객체를 println, printf 문자열 연결 연산자(+) - assert 구문에 넘길 때 혹은 디버거가 객체를 출력할 때 자동으로 불린다 - toString을 재정의하지 않는다면 쓸모없는 메시지만 로그에 남는다 실전에서 t.. 2021. 10. 3.
11. equals를 재정의하려거든 hashCode도 재정의하라 equals를 재정의한 클래스 모두에서 hashCode도 재정의해야 한다 그렇지 않으면 hashCode 일반 규약을 어기게 되어 해당 클래스의 인스턴스를 HashMap이나 HashSet 같은 컬렉션 원소로 사용할 때 문제를 일으킨다 Object 명세에서 발췌한 규약 1. equals비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체의 hashCode 메서드는 몇번을 호출해도 일관되게 항상 같은 값을 반환해야 한다 단, 애플리케이션을 다시 실행한다면 이값이 달라져도 상관없다 2. equals가 두 객체를 같다고 판단했다면, 두 객체의 hashCode는 똑같은 값을 반환해야 한다 3. equals가 두 객체를 다르다고 판단했더라도, 두 객체의 hashCode가 서로 다른 값을 반.. 2021. 10. 2.
728x90