Skip to content

The source code from the third edition of Effective Java, with minor additions as necessary to make it runnable.

Notifications You must be signed in to change notification settings

jongheonleee/effective_java

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 

Repository files navigation

🚀 Effective Java

📌 02. 객체 생성과 파괴



📦 Item 01. 생성자 대신 정적 팩터리 메서드를 고려하라

무분별하게 new 생성자()로 객체를 생성하는 것을 지양, 정적 팩터리 메서드 활용하여 자원 효율적으로 사용, 객체 적극적으로 재사용

  • 정적 팩터리 메서드 : static 팩토리 메서드를 의미

  • new 연산자를 통한 객체 생성은 자원을 낭비함, new 를 사용하면 heap영역에 항상 메모리 공간이 확보됨

  • 따라서, 객체를 효율적으로 생성하기 위해서 정적 팩터리 메서드 사용

  • 장점

    • (1) 이름을 갖음 - 메서드 여러개 만들 수 있음
    • (2) 인스턴스 재사용 - 불필요하게 인스턴스를 반복해서 생성할 필요 없이 재사용할 수 있음(flyweight 패턴)
    • (3) 다형성, 공변이 가능함 - 반환할 클래스를 자유롭게 선택 가능. 예를 들어, Car car = CarFactory.getInstance("sportCar");
    • (4) 매개변수에 따라 다른 객체 반환 - CarFactory.getInstance("truck"), CarFactory.getInstance("sportCar"), ...
    • (5) 정적 팩터리 메서드를 작성할 때, 반환 객체 클래스가 존재하지 않아도됨 - Future 패턴과 유사(빈 박스제공)
  • 단점

    • (1) 상속 불가능 - 생성자가 private 이기 때문
    • (2) 메서드 찾기 어려움 - 이름이 여러개임

📦 Item 02. 생성자에 매개변수가 많다면 빌더를 고려하라

iv가 많고 객체 생성시에 매개변수가 많은 경우, 생성자나 정적 팩터리 메서드보단 빌더 패턴을 활용

  • 빌더 패턴 : "생성자에 매개변수가 많음 -> 생성자 오버로딩 많이함, 매개변수 순서 혼동" 해결하기 위해 내부적으로 빌더 클래스를 정의해서 해당 클래스를 생성할 때 사용

📦 Item 03. private 생성자나 열거 타입으로 싱글턴임을 보증하라

열거형으로 싱글톤 만드는 방식이 가장 좋음

  • 싱글톤 : 인스턴스 하나만 생성하고 공유
  • 구현 방법 - (1) public static final -> (2) 정적 팩터리 메서드 -> (3) 열거형

📦 Item 04. 인스턴스화를 막으려거든 private 생성자를 사용하라

private 생성자를 통해 인스턴스화 막음

  • 굳이 이렇게 까지 할 필요는 없음, 물론 싱글톤같은 디자인 패턴에는 적용해야함

📦 Item 05. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

인스턴스 생성시 필요한 자원을 넘겨줌, 메서드로 넘겨줄 수도 있음(sort("비교대상", "비교기준"))

  • 전략 패턴, 알고리즘을 외부에서 통째로 넣어줌
  • 예시에서 나온 맞춤법 검사기의 문제점은 "자주 변경될 부분이 구체적으로 작성되어 있음"
  • 예를 들어, 언어마다 맞춤법이 다르기 때문에 해당 부분을 쉽게 변경할 수 있게 구현해야함(전략 패턴)

📦 Item 06. 불필요한 객체 생성을 피하라

재사용 가능한 객체는 공유해서 사용하자

  • 멀티 쓰레드 환경도 고려해야함
  • 재사용 가능한 객체라는 의미는 공유 가능한 정보를 갖고 있냐도 포함임
  • 즉, 내부 iv가 불변이 아닌 경우, 또한 동기화 처리가 안되있는 경우는 멀티 쓰레드 환경에서 공유해서 사용할 경우 프로그램에 혼동을 야기할 수 잇음

📦 Item 07. 다 쓴 객체 참조를 해제하라!

  • 가비지 컬렉터가 사용되지 않는 객체를 회수하지만, 100% 회수해주지 않음
  • 참조가 걸려있지만 사용하지 않는 경우에는 회수하지 못함
    • 대표적으로 Flyweight 패턴에서 맵에 저장된 안쓰는 객체 회수 못함
  • 위와 같은 경우는 개발자가 참조를 해제해야함

📦 Item 08. finalizer와 cleaner 사용을 피하라


📦 Item 09. try-finally 보다는 try-with-resources를 사용하라


📌 03. 모든 객체의 공통 메서드



📦 Item 10. equals는 일반 규약을 지켜 재정의하라

  • 핵심은 "구체 클래스를 확장해 새로운 값을 추가하면서 equals() 규약을 만족시킬 방법은 존재하지 않는다."

  • equals()를 오버라이딩 하지 않아야하는 상황

    • (1) 각 인스턴스는 고유함 : 기본적으로 참조 비교가 정상임
    • (2) 인스턴스의 '논리적 동치성'을 검사할 일이 없음 : 값 비교(논리적 동치성)를 의미함
    • (3) 조상에서 재정의한 equals()가 자손에서도 딱 들어맞는다
      • 조상, 자손은 iv의 개수가 같거나 다름
      • 자손에서 iv가 추가되고 equals()를 오버라이딩 하면 문제가 발생
        • 동치관계(빈사성, 대칭성, 추이성, 일관성, null-아님) 충족 못함

  • 양질의 equals()를 오버라이딩 하기 위한 규칙
    • (1) == 연산자를 사용해 입력이 자기 자신인지 확인
    • (2) instanceof 를 통해 타입 확인
    • (3) 대응되는 '핵심' 필드들이 모두 일치하는지 하나씩 확인
    • (4) 대칭적? 추이성? 일관적? 스스로 자문

📦 Item 11. equals를 재정의하려거든 hashCode도 재정의하라

  • 핵심은 "equals()를 재정의한 클래스 모두 hashCode를 재정의해야함"
  • 같은 객체는 같은 해시코드를 반환해야 하기 때문
  • 해시코드(hashCode) : 디지털 지문, 디지털 증거용으로서 많이 사용함, 파일을 건드리면 디지털 지문이 변경됨
  • 해시코드를 얻기 위해 호출할 때 마다 해시 값을 매번 계산할 필요 없음
    • 한번만 계산하고 저장 해두었다가 그 값을 반환
    • 해시값은 불변
  • hashCode() 메서드의 경우, 스레드 안정성까지 고려해야함

📦 Item 12. toString을 항상 재정의하라

  • 기본적으로, 클래스_이름@16진수_해시코드
  • 모든 하위 클래스에서 toString을 재정의, 그 객체가 가진 주요 정보 모두 반환
    • 디버깅 용이
    • 객체 정보 파악 용이

📦 Item 13. clone 재정의는 주의해서 하라

  • Cloneable 인퍼테이스, clone 가능한 클래스 임을 의미
  • clone은 원본 객체에 영향 x, 복제된 객체의 불변식을 보장해야함
  • 주의할 점
    • 깊은 복사 vs 얕은 복사
    • 동기화 처리
  • 복사 생성자, 복사 팩터리 활용 할 수 있음
  • 왠만하면 "복제 기능은 생성자와 팩터리를 이용하는게 좋음"

📦 Item 14. Comparable을 구현할지 고려하라

  • 기본 비교 기준, 기본 비교 기준 이외 Comparator로 구현
  • 동치성 + 순서 비교, 객체의 순서 비교
  • 반사성, 대칭성, 추이성 충족
  • <와 >는 추천하지 않음, == 과 compareTo() 활용

About

The source code from the third edition of Effective Java, with minor additions as necessary to make it runnable.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%