[Effective Java] Chapter2 객체 생성과 파괴

2022. 2. 3. 09:00· BOOK/[이펙티브 자바]
목차
  1. 1. 생성자 대신 정적 팩터리 메서드를 고려하라
  2. 1.1 장점
  3. 1.2 단점
  4. 2. 생성자에 매개변수가 많다면 빌더를 고려하라
  5. 2.1 장점
  6. 2.2 단점
  7. 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라
  8. 4. 인스턴스화를 막으려거든 private 생성자를 사용하라
  9. 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
  10. 6. 불필요한 객체 생성을 피하라
  11. 7. 다 쓴 객체 참조를 해제하라
  12. 8. finalizer와 cleaner 사용을 피해라
  13. 9. try-finally보다는 try-with-resource를 사용하라
  14. ※ 참고

Chapter2 객체 생성과 파괴

 

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

1.1 장점

  1. 이름을 가질 수 있음 → 반환될 객체의 특성을 쉽게 묘사할 수 있음
  2. 호출될 때마다 인스턴스를 새로 생성하지는 않아도 됨 → 객체의 생성 비용을 줄일 수 있음
  3. 반환 타입의 하위 타입 객체를 반환할 수 있음 → 유연성↑
  4. 반환 타입의 하위 타입이기만 하면, 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있음 → 유연성↑
  5. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 됨
  6. → interface안에 static 메서드를 구현하여 가능하게 함

 

1.2 단점

  1. 상속을 하려면 public이나 protected 생성자가 필요하므로 정적 팩터리 메서드만으로 하위 클래스를 만들 수 없음.
  2. 정적 팩터리 메서드는 프로그래머가 찾기 어려움 → API 설명에 자세히 나오지 않으므로 정적 팩터리 메서드 명명 방식을 따라야 함
    • from: 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환하는 형변환 메서드
    • of: 여려 매개변수를 받아 적합한 타입의 인스턴스를 반환하는 집계 메서드



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

2.1 장점

  • 빌더 패턴은 매개변수가 많을때, 더 좋은 가독성을 제공해 준다
    • 클래스 안에 내부 클래스로 구현하여 쓰인다 → 추상 클래스에서는 내부 추상클래스로 변경하여 사용
  • 점층적 생성자 패턴으로 사용할 때
  • // 점층적 생성자 패턴 class User { //필수 private final String name; private final int age; //선택 private int weight; private String address; public User(String name, int age) { this(name, age, 0, ""); } public User(String name, int age, int weight) { this(name, age, weight, ""); } public User(String name, int age, String address) { this(name, age, 0, address); } public User(String name, int age, int weight, String address) { this.name = name; this.age = age; this.weight = weight; this.address = address; } }

→ 너무 많은 생성자가 필요하고, 생성자를 사용할 때 가독성이 좋지 않다.

​ User user = new User("kim", 20, 70, "서울")

  • 빌더 패턴을 사용할 때
  • class User_Builder { private final String name; private final int age; private final int weight; private final String address; public User_Builder(Builder builder) { name = builder.name; age = builder.age; weight = builder.weight; address = builder.address } static class Builder { //필수 private final String name; private final int age; //선택 - 기본값으로 초기화 private int weight = 0; private String address = ""; public Builder(String name, int age) { this.name = name; this.age = age; } public Builder age(int val) { weight = val; return this; } public Builder address(String val) { address = val; return this; } public User_Builder build() { return new User_Builder(this); } } }

​ → 코드가 더 길어졌지만, 새로운 객체를 만들때 가독성은 더 올라갔다.

​ User_Builder user = new User_Builder("kim", 20).weight(70).address("서울").build()

2.2 단점

  • 객체를 만들려면, 빌더부터 만들어야 함
  • 성능에 안좋은 영향을 미칠 수 있음



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



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

  • staic 메서드와 static 필드를 갖는 클래스를 만들때가 있는데(객체지향적으로 좋지 못함), 이때 생성자를 명시하지 않으면 컴파일러가 자동으로 매개변수를 받지 않는 public 생성자를 만들어주는데, 이는 다른 사용자들에게 있어서 이 생성자를 직접 만든것인지 아니면 자동으로 만든것인지 알 수 없게한다.
    • 따라서 private 생성자를 추가하여 클래스의 인스턴스화를 막아야 한다.



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

  • 많은 클래스들이 하나 이상의 자원을 사용하는데, 이때 자원들이 static final로 구현되는 것을 볼 수 있는데, 이는 확장성에서 유연하지가 않다
    • 따라서 의존 객체 주입을 사용해서 자원을 사용해야 한다 → 유연성, 재사용성, 테스트 용이성 개선
    • 자원에 따라서 클래스의 동작이 바뀌면 정적 유리틸리티 클래스나 싱글톤을 사용하지 않는것이 낫다.
  • 정적유틸리티 사용 ex)
  • class FindRoutine { private final Transportation transportation = new Car; private FindRoutine() { } public static int distance() { ... } public static int routine() { ... } }
  • 의존 객체 주입 사용
  • class FindRoutine { private final Transportation transportation ; public FindRoutine(Transportation transportation) { this.transportation = Objects.requireNonNull(transportation); } public static int distance() { ... } public static int routine() { ... } }



6. 불필요한 객체 생성을 피하라

  • String s = new String("kim"); 보다 String s = "kim";과 같은 리터럴을 이용하여 초기화하는 것이 반복적인 객체 생성을 막아 성능이 향상되게 할 수 있다.



7. 다 쓴 객체 참조를 해제하라

  • 다 사용한 객체는 null을 이용하여 참조를 해제할 수 있다.
    • ex) elements[index] = null;
  • 모든 객체에 적용하는 것은 바람직하지 않고, 메모리나 캐시를 직접 관리하는 클래스(ex) 스택)에서 가비지 컬렉터가 인지 못할 경우에 처리해야 한다.



8. finalizer와 cleaner 사용을 피해라

  • finalizer와 cleaner는 불확실성과 성능 저하가 발생하므로 사용을 피해야 한다.



9. try-finally보다는 try-with-resource를 사용하라

  • try-finally는 주로 자원을 close하는 데 많이 쓰이는데, 복수의 자원이 들어오면 코드의 가독성이 떨어지기 때문에 try-with-resource를 사용해야한다.
    • try와 함께 자원을 선언하여 try 구문이 끝나고 나면 자동으로 자원이 사라지게 해준다.
  • /*
    try (자원) {
      ...
    }
    */
    
    static void copy(String src, String dst) throws IOException {
            try (InputStream in = new FileInputStream(src); // 자원 두개를 try와 함께 선언
                 OutputStream out = new FileOutputStream(dst)) {
                byte[] buf = new byte[BUFFER_SIZE];
                int n;
                while ((n = in.read(buf)) >= 0) {
                    out.write(buf, 0, n);
          }
       }
    }



※ 참고

  • 이펙티브 자바 - 조슈아 블로크
저작자표시 (새창열림)

'BOOK > [이펙티브 자바]' 카테고리의 다른 글

[Effective Java] Chapter7 람다와 스트림  (0) 2022.03.17
[Effective Java] Chapter6 열거 타입과 애너테이션  (0) 2022.03.15
[Effective Java] Chapter5 제네릭  (0) 2022.02.15
[Effective Java] Chapter4 클래스와 인터페이스  (0) 2022.02.10
[Effective Java] Chapter3 모든 객체의 공통 메서드  (0) 2022.02.08
  1. 1. 생성자 대신 정적 팩터리 메서드를 고려하라
  2. 1.1 장점
  3. 1.2 단점
  4. 2. 생성자에 매개변수가 많다면 빌더를 고려하라
  5. 2.1 장점
  6. 2.2 단점
  7. 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라
  8. 4. 인스턴스화를 막으려거든 private 생성자를 사용하라
  9. 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
  10. 6. 불필요한 객체 생성을 피하라
  11. 7. 다 쓴 객체 참조를 해제하라
  12. 8. finalizer와 cleaner 사용을 피해라
  13. 9. try-finally보다는 try-with-resource를 사용하라
  14. ※ 참고
'BOOK/[이펙티브 자바]' 카테고리의 다른 글
  • [Effective Java] Chapter6 열거 타입과 애너테이션
  • [Effective Java] Chapter5 제네릭
  • [Effective Java] Chapter4 클래스와 인터페이스
  • [Effective Java] Chapter3 모든 객체의 공통 메서드
쿠엔크
쿠엔크
우아한테크코스 5기 BE 에단 Github : https://github.com/cookienc
쿠엔크
기러기는 기록기록
쿠엔크
전체
오늘
어제
  • 분류 전체보기 (132)
    • CS (46)
      • [OS] (12)
      • [NETWORK] (10)
      • [DATABASE] (11)
      • [BASIC CONCEPT] (1)
      • [DATA STRUCTURE] (7)
      • [ALGORITHM] (5)
    • LANGUAGE (17)
      • [JAVA] (17)
    • DESIGN_PATTERN (2)
    • FRAMEWORK (18)
      • [SPRING] (18)
    • ORM (11)
      • JPA (11)
    • AWS (7)
    • BOOK (10)
      • [자바 웹 개발 워크북] (3)
      • [이펙티브 자바] (7)
    • 개발 (19)
      • [오류] (7)
      • [고민] (1)
      • [우테코] (10)
      • [iTracker] (1)
    • Tip (1)
      • [Plugins] (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 가비아
  • 오류
  • 알고리즘
  • 개념
  • ArgumentResolver
  • 디자인 패턴
  • JVM
  • 자바 웹 개발 워크북
  • HTTP
  • Effective Java
  • aws
  • java
  • JPA
  • 자료구조
  • 스프링
  • 운영체제
  • 데이터베이스
  • CORS
  • 네트워크
  • Spring

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
쿠엔크
[Effective Java] Chapter2 객체 생성과 파괴

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.