IT 서적/이펙티브 자바

이펙티브 자바

수달하나 2023. 10. 19. 23:44

2장. 객체 생성과 파괴

올바른 객체 생성 방법과 불필요한 생성을 피하는 방법, 객체의 소멸을 보장하고 소멸 전 수행해야 할 정리 작업을 관리하는 요령을 확인.

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

클래스 생성자와는 별도로 정적 팩터리 메서드를 제공할 수 있는데 정적 팩터리 메서드를 통해 그 클래스의 인스턴스를 반환.

정적 팩터리 메서드를 통한 장점은 다음과 같다

  • 특정 이름을 통하여 인스턴스를 반환 받을 수 있다.
  • 호출될 때마다 인스턴스를 새로 생성하지 않도록 할 수 있다.
  • 반환 타입의 하위 타입 객체를 반환할 수 있다.
  • 입력 매개변수에 따라서 다른 객체를 반환할 수 있다.
  • 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.

하지만 정적 팩터리 메서드를 사용함에 있어서 단점도 존재한다.

  • 정적 팩터리 메서드만 자공하고 생성자를 통해서 만들수 없는 클래스의 하위 클래스를 정의 할 수 없다.
  • 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.

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

점층적 생성자 패턴도 쓸 수는 있지만 매개변수의 개수가 많아지면 클라이언트 코드를 작성하거나 읽기가 어려워진다.

따라서 점층적 생성자 패턴의 안전성과 자바빈즈 패턴의 가독성을 겸비한 빌더 패턴을 사용하는것이 좋다.

또한 빌더 패턴은 계층적으로 설계된 클래스와 함께 쓰기에 좋다.

 

생성자나 정적 팩터리가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는 게 더 낫다. 매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그러며 빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간편하고 자바빈즈보다 훨씬 안전하다.

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

싱글턴을 만드는 방식은 보통 둘 중 하나다. 두 방식 모두 생성자는 private 으로 감춰두고, 유일한 인스턴스에 접근할 수 있는 수단으로 public static 멤버를 하나 마련해두는 것이다. 

  • public static final 필드 선언을 통한 외부 참조
  • 정적 메서드를 통한 인스턴스 반환

정적 메서드를 통한 인스턴스의 반환의 경우 API를 변경하지 않으면서 싱글턴이 아니게 되도록 변경할 수 있다는 측면에서 확장성이 높다.

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

추상 클래스로 만드는 것으로는 인스턴스화를 막을 수 없다. 따라서 인스턴스 생성을 막기위해 추상클래스를 사용하는 것은 옳지 않다. 컴파일러가 기본 생성자를 만드는 경우는 오직 명시된 생성자가 없을 경우이기 때문에 인스턴스 생성을 막고 싶다면 private 생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다.

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

클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다. 이 자원들은 클래스가 직접 만들게 해서도 안 된다. 대신 필요한 자원을 생성자에 넘겨주어서 의존 객체 주입이라 하는 기법을 통해 클래스의 유연성, 재사용성, 테스트 용이성을 개선할 수 있다.

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

객체가 불변이라면 재사용을 통해 불필요한 객체 생성을 피해야 한다.

또한 박싱된 기본타입 예를 들어 Long 보다는 기본타입 long 을 사용하고, 의도치 않은 오토박싱이 숨어들지 않도록 주의해야 한다.

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

해당 참조를 다 썼을 때 null 처리를 통해 참조를 해제할 수 있다.

모든 객체를 다 쓰자마자 일일이 null 처리를 할 필요는 없기 때문에 객체 참조를 null 처리하는 일은 예외적인 경우여야 한다. 일반적으로 메모리 누수를 일으 킬 수 있는 경우에 참조를 해제해야 한다.

아이템8. finalizer와 cleaner 사용을 피하라

finalizer 와 cleaner 를 대신하기 위해 AutoCloseable을 구현해주고 클라이언트에서 인스턴스를 다 쓰고 나면 close 메서드를 호출하는 방식을 통해 다 사용한 객체를 참조를 해제 할 수 있다.

아이템9. try-finally보다는 try-with-resources를 사용하라

반드시 회수해야 하는 자원을 다룰 때는 try-finally 말고, try-with-resources를 사용해야 한다. 이 사실에 있어서 예외는 없으며 결과적으로 코드는 더 짧고 분명해지며 만들어지는 예외 정보도 훨씬 유용하다.

결과적으로 try-with-resources 로는 정확하고 쉽게 자원을 회수 할 수 있다.