본문 바로가기

Effective Java73

[Effective Java] 아이템7 다 쓴 객체 참조를 해제하라 ■ 메모리 누수가 일어나는 예시 코드 자바언어처럼 가비지 컬렉터를 갖춘 언어로 넘어오면 다 쓴 객체를 알아서 회수해가니 메모리 관리를 더이상 신경쓰지 않는다고 착각할 수 있다. 다음 스택 코드를 살펴보면 스택에서 꺼내진 객체들은 가비지 컬렉터가 회수하지 않는다. 프로그램에서 그 객체들을 더이상 사용하지 않더라도 말이다. 이 스택이 다 쓴 참조를 여전히 가지고 있기 때문이다. 여기서 다 쓴 참조란 문자 그대로 앞으로 다시 사용하지 않을 참조를 뜻한다. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Object[] ge.. 2021. 1. 17.
[Effective Java] 아이템6 불필요한 객체 생성을 피하라 ■ String 리터럴을 이용한 불필요한 객체 생성 방지 똑같은 기능의 객체를 매번 생성하지 말고 객체 하나를 재사용하는 편이 나을 때가 많다. 특히 불변 객체는 언제든 재사용할 수 있다. String의 경우에 이를 한번 생각해 볼 수 있다. String의 두가지 생성 방식에 대해서 간단히 알아보겠다. 1. new 연산자를 이용한 방식 2. 리터럴을 이용한 방식 new를 이용하여 String을 생성하면 Heap 영역에 존재하게 된다. 그리고 리터럴을 이용할 경우 String pool 이라는 영역에 존재하게 된다. 이를 이용하여 단 하나의 문자열 객체만을 생성하고 캐싱할 수 있다. String a = "Hello"; String b = "Hello"; String c = new String("Hello").. 2021. 1. 16.
[Effective Java] 아이템5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 많은 클래스가 하나 이상의 자원(Resource)에 의존한다. 간혹 정적 유틸리티나 싱글턴에서 이러한 자원을 내부적으로 명시하고 있는 경우가 있다. 아래 예시 코드에서는 두 방식 모두 사전을 하나만 사용한다. 실전에서는 사전이 언어별로 따로 있고 특수 어휘용 사전을 별도로 두기도 하기 때문에 사전 하나로 대응 하나로 모든걸 대응한다는건 안좋은 설계이다. 정적 유틸리티를 잘못 사용한 예시 코드 // 정적 유틸리티 - 잘못된 예 public class SpellChecker { private static final Lexicon dictionary = new Lexicon(); // 특정 자원을 명시 private SpellChecker() {} // 인스턴스화 방지 - 아이템 4 // ...생략... } .. 2021. 1. 14.
[Effective Java] 아이템4 인스턴스화를 막으려거든 private 생성자를 사용하라 1. 정적 메서드와 정적 필드만 담은 클래스 생성 정적 메서드와 정적 필드만 담을 클래스 또는 final 클래스와 관련한 메서드들을 모아놓을 경우가있다. 정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계한게 아니기 때문에 private 생성자를 사용하면 된다. 예를들면 java.util.Collections 처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓는 경우 private 생성자를 사용한다. private 생성자에 이런 주석을 담으면 의도를 좀 더 명확하게 할 수 있다. //기본 생성자가 만들어지는 것을 막는다.(인스턴스화 방지용) private Collections() { } 2.정리 클래스의 인스턴스화를 막으려면 private 생성자를 추가하면 된다. pri.. 2021. 1. 13.
[Effective Java] 아이템3 private 생성자나 열거 타입으로 싱글턴임을 보증하라 1. 싱글턴(Singleton) 싱글턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 전역 변수이기 때문에 프로그램 내부에서 이 객체를 공유하며 사용한다. 싱글턴 생성 방식1 - public static final 방식 //public static final 필드 방식의 싱글턴 public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis(){...}; } private 생성자는 public static final 필드인 Elvis.INSTANCE를 초기화할 때 딱 한번 호출 public 이나 protected(같은 패키지 or 상속 받을 시 접근 가능) 생성자가 없으므로 Elivis 클래스가 초기화 .. 2021. 1. 13.
[Effective Java] 아이템2 생성자에 매개변수가 많다면 빌더를 고려하라 1. 정적 팩터리와 생성자의 문제점 정적 팩터리와 생성자는 선택적 매개변수가 많을 때 적절히 대응하기 어렵습니다. 대부분 점층적 생성자 패턴을 즐겨 사용하는데 이런 생성자는 사용자가 설정하고 싶지 않은 매개변수까지 포함하기 때문에 어쩔 수 없이 그런 매개변수도 값을 지정해줘야한다. 매개변수가 늘어날수록 걷잡을 수 없다. 2. 자바빈즈패턴 두번째 대안인 자바빈즈패턴을 사용하면 매개변수가 없는 생성자로 객체를 만든 후 세터 메서드들을 호출하여 원하는 매개변수의 값을 설정하는 방식이 있다. 자바빈즈패턴은 객체 하나를 만들려면 메서들르 여러번 호출해야하고 객체가 완전히 생성되기 전까지는 일관성이 무너진 상태에 놓이게 된다. 일관서이 깨진 객체가 만들어지면 버그를 심은 코드와 그 버그 때문에 런타임에 문제를 겪는.. 2021. 1. 12.