본문 바로가기

programming/java

(17)
Item 15. 클래스와 멤버의 접근 권한을 최소화하라 [WHY] 잘 설계된 컴포넌트는 얼마나 정보 은닉(캡슐화)를 고려했는지 여부이다. 내부 요소를 외부에 최소한으로 노출하기 위해서 접근 권한을 최소화하는 것이다. [WHEN] 컴포넌트를 설계할 때. [HOW] 꼭 필요한 것만 골라 최소한의 public API를 설계하자. 그 외에는 클래스, 인터페이스, 멤버가 의도치 않게 API로 공개되는 일이 없도록 해야 한다. public 클래스는 상수용 public static final 필드 외에는 어떠한 public 필드도 가져서는 안 된다. public static final 필드가 참조하는 객체가 불변인지 확인하라. [캡슐화] 정보 은닉(캡슐화)의 장점 시스템 개발 속도를 높인다. 시스템 관리 비용을 낮춘다. 성능 최적화에 도움을 준다. 소프트웨어 재사용성을 ..
Item 14. Comparable을 구현할지 고려하라. [WHY] Comparable을 구현한 객체들의 배역은 손쉽게 정렬할 수 있다 검색, 극단 값 계산, 자동 정렬되는 컬랙션 관리도 쉽게 할 수 있다. [WHEN] 알파벳, 숫자, 연대 같이 순서가 명확한 값 클래스를 작성할 때 [HOW] compareTo 규약 두 객체의 참조를 바꾸어도 예상한 결과가 나와야 한다. 추이성을 만족시켜야 한다. a 은 오류를 유발할 가능성을 내포하고 있기 때문에 정적 메서드 사용을 더 권고한다. 특히 실수 타입을 비교할 때는..
Item 13. clone 재정의는 주의해서 진행하라. [WHY] Object.clone() 은 깊은 복사를 보장하지 않느다. Object.clone() 은 동기화를 고려하지 않는다. [WHEN] clone() 메서드를 구현할 때. [HOW] 복사 생성자, 복사 팩터리를 이용해서 안전한 복사(깊은 복사)를 구현하자. 부득이하게 Cloneable을 구현한 객체를 사용해야한다면 깊은 복사가 되도록 clone()메서드를 구현하자.
Item 12. toString을 항상 재정의하라. [WHY] toString을 잘 구현할 클래스는 사용하기 편하고 디버깅이 용이하다. ex) assert구문을 넘길 때, 디버거가 객체를 출력할 때, toString이 호출된다. [WHEN] 대상 : 하위 클래스들이 공유해야 할 문자열 표현이 있는 추상 클래스 예외 대상 : 정적 유틸리티 클래스, 열거타입 [HOW] 실전에서 toString을 그 객체가 가진 주요 정보를 모두 반환하는 것이 좋다. 하지만 객체가 너무 비대하다면 요약된 정보를 반환하는 것도 방법이다. 포맷을 명시할지 결정하여 문서화를 한다. 이때 설계자의 의도를 명확하게 명시해야한다. toString의 결과에서 필요한 정보를 추출하는 것은 성능적으로 손해이고 더 좋은 방법이 있다. 다른 getter 함수(API)를 생성하여 추출의 책임을 다..
Item 11. equals 재정의할 때 hashCode도 정의하라 [Why] hashCode를 재정의하지 않으면 해시를 이용한 컬랙션을 사용할 때 해시의 빠른 속도를 활용하지 못한다. [When] hashCode를 재정의할 때 [How] hashCode 일반 규약 equals 비교에 사용되는 정보가 변경되지 않았다면, hashCode 도 변하면 안 된다.(애플리케이션을 다시 실행한다면 이 값이 달라져도 상관 없음) equals가 두 객체가 같다고 판단했다면, 두 객체의 hashCode는 똑같은 값을 반환한다.→ 논리적으로 같은 객체는 같은 해시코드를 반환해야 한다. equals가 두 객체를 다르다고 판단했더라도, hashCode는 꼭 다를 필요는 없다.하지만, 다른 객체에 대해서는 다른 값을 반환해야 해시테이블의 성능이 좋아진다. hashCode를 작성하는 요령 int..
Item 10. equals 일반 규약을 지켜 재정의하라 equals 재정의가 필요하지 않은 경우 동치 관계인 인스턴스가 없다. (각 인스턴스가 본질적으로 고유하다) 생성한 인스턴스가 모두 다르다는 것 → 비교하는 것이 무의미하다. equals를 사용할 일이 없다. 인스턴스의 논리적 동치성(logical equality)를 검사할 일이 없다. equals 메서드를 사용할 경우가 없는 경우 클래스가 private 이거나 package-private 인 경우 쓸데없다. 상위 클래스에 구현된 equals를 그대로 사용하는 경우 equals 메서드 재정의 일반 규약 equals 메서드는 동치관계 (equivalence relation)를 구현하며, 다음 특성을 만족한다. 반사성(reflexivity) : null 이 아닌 모든 참조 값 x에 대해 x.equals(x)..
Item 9. try-finally 보다는 try-with-resources를 사용하라 [Why] 코드를 더 짧고 분명하게 만들 수 있기 때문 -> 가독성 향상 예외 정보를 추적하기 유용하다. [When] close() 메서드를 이용해서 자원을 회수해야하는 객체를 제거할 때 [How] try(BufferedReader br = new BufferedReader(new FileReader(path)){ return br.readLine(); } catch(Exception e){ e.printStackTrace(); } finally{ br.close(); } [GC가 있는데 왜 close()] 자바의 메모리 관리는 가비지 컬렉터에서 자동으로 처리해주기 때문에 왜 close()를 호출을 해서 자원을 명시적으로 회수를 해야하는지 궁금했다. 가비지 컬렉터는 JVM 에서 관리하는 메모리 영역을 정..
Item 8. finalizer와 cleaner의 사용을 피하라 [Why] 위험하기 때문이다. (예측 불가능, 느림) 즉시 수행되지 않는다. 수행 시점 뿐만 아니라 수행 여부도 보장하지 않는다. finalizer는 보안 문제를 일으킬 가능성이 있다. [When] 되도록 사용하지 않는 것을 권장 제 때 실행되어야 하는 작업은 반드시 피하라 상태를 영구적으로 수정하는 작업은 반드시 피하라 [How] AutoCloseable을 구현하고 close 메서드를 호출하는 방법을 사용하라. 프로그래머의 실수를 방지하는 용도로 사용하라 close 메서드 호출을 하지 않는 경우에는 객체를 방치하는 것보다 finalizer, cleaner를 통해서 객체를 닫는 안전망을 추가하는 것이 낫다. 가비지 컬렉터가 접근하지 못하는 네이티브 피어와 연결된 객체를 회수할 때 사용하라. 단 이 경우도..