
Effective Java 9. try-with-resources를 사용하자
2022. 10. 4. 23:36
Java/Effective Java
try-finally 전통적으로 자원이 제대로 닫힘을 보장하기 위해서는 try-finally가 쓰였다. 하지만 해당 방식은 아래와 같이 두 가지 문제점이 있다. 문제점 자원이 많아질 수록 try 중첩문이 발생하여 복잡해진다. 아래 예시에서 try 문에서 exception 이 발생할 경우, finally 문에서도 exception 이 발생한다. 그럼 finally 문의 로그만 남아 실제로 try 문에서 난 에러는 surpressed 되며, 디버깅하기가 힘들어진다. try { return br.readLine(); } finally { br.close(); } 실제고, 2007년 당시 자바 라이브러리에서 close 를 제대로 구현한 비율은 3분의 1정도라고 한다. try-with-resources 이에 대한..

Effective Java 7. 다 쓴 객체 참조를 해제하라
2022. 1. 22. 21:03
Java/Effective Java
Stack으로 본 객체 참조 해제 아래의 Stack 클래스 코드를 확인해보고 문제가 될 만한 부분을 찾아보자. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop() { if (size == 0) { throw new EmptyStackException();..

Effective Java 6. 불필요한 객체 생성을 피하라
2022. 1. 6. 23:34
Java/Effective Java
불필요한 객체 생성은 왜 피해야 할까? 똑같은 기능의 객체를 매번 생성하기 보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 재사용은 빠르고 세련되다. 특히 불변 객체(아이템 17) 은 언제든 재사용할 수 있다. 방법 1. String 객체는 새로 생성하지 말자 // 1. 잘못된 예 String s = new String("bikini"); // 2. 옳은 예 String s = "bikini"; 1번의 예시는 실행될 때마다 새로운 String 객체를 생성한다. 반복문이나 빈번히 호출되는 메서드의 경우 인스턴스가 수백만개 생성될 수 있다. 이러한 경우에는 새로운 인스턴스를 매번 생성하는 대신 하나의 String 인스턴스를 사용하자. 이 방식을 사용한다면 같은 가상 머신 안에서 똑같은 문자열 리터럴을 ..

Effective Java 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
2022. 1. 4. 00:10
Java/Effective Java
많은 클래스는 하나 이상의 자원에 의존한다. 예를 들어, 맞춤법 검사기를 생각해보자. 맞춤법 검사기는 사전에 의존한다. 따라서, 사전 하나로 모든 맞춤법 검사를 하는 것은 불가능하다. 맞춤법 검사는 사용하는 사전에 따라서 동작이 달라진다. 이러한 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. 이러한 경우, 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식인 의존 객체 주입을 사용한다. 샘플 코드 public class SpellChecker { private final Lexicon dictionary; public SpellChecker(Lexicon dictionary) { this.dictionary = dictionary; } //...

Effective Java 4. 인스턴스화를 막으려거든 private 생성자를 사용하라
2022. 1. 2. 14:00
Java/Effective Java
언제 인스턴스화를 막는 것이 필요할까? 1. 단순히 정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때 사용한다. - 예를 들면, java.lang.Math, java.util.Arrays, java.util.Collections 2. 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(혹은 팩터리)를 모아놓는다. 3. final 클래스와 관련한 메서드들을 모아놓을 때 사용한다. - final 클래스를 상속해서 하위 클래스에 메서드를 넣는 것은 불가능하다. 그럼 어떻게 인스턴스화를 막을 수 있을까? 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들어준다. 실제로 공개된 API들에서도 이처럼 의도치 않게 인스턴스화를 할 수 있게 된 클래스가 종종 있다. 1. 추상 클래스로 만드는..

Effective Java 3. 생성자나 열거 타입으로 싱글턴임을 보증하라
2021. 12. 28. 01:00
Java/Effective Java
오늘은 싱글턴을 만드는 방법에 대해 알아보겠다. 싱글턴을 만드는 방법에는 아래와 같이 세 가지 방식이 있다. 싱글턴을 만드는 방법 1. public static final 필드 방식의 싱글턴 생성자는 private으로 감춰두고, 유일한 인스턴스에 접근할 수 있는 수단으로 public static final 멤버를 마련한다. public class Elvis1 { public static final Elvis1 INSTANCE = new Elvis1(); private Elvis1() { } } 이 방식의 장점은 아래와 같다. public static 필드라 final이니 해당 클래스가 싱글턴임이 API에 명백하게 드러난다. 간결하다. 싱글턴을 만드는 방법 2. 정적 팩터리 방식의 싱글턴 생성자는 priv..

Effective Java 2. 생성자에 매개변수가 많다면 빌더를 고려하라
2021. 12. 25. 23:42
Java/Effective Java
객체 생성은 생성자를 통해 하거나 아이템 1에서 공부한 것처럼 정적 팩토리 메서드를 사용할 수 있다. 이제 매개변수가 많아질 때에 어떻게 객체 생성을 할 수 있을지 알아보자. 점층적 생성자 패턴(telescoping constructor pattern) 정적 팩터리와 생성자에는 똑같은 제약이 있다. 바로 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 점이다. 이럴 때, 프로그래머는 샘플 코드와 같이 점층적 생성자 패턴(telescoping constructor pattern)을 즐겨 쓴다. public class NutritionFacts { ... public NutritionFacts(int servingSize, int servings, int calories) { this(servingSiz..

Effective Java 1. 생성자 대신 정적 팩터리 메서드를 고려하라.
2021. 12. 24. 06:16
Java/Effective Java
오늘은 Effective Java의 첫 번째 아이템을 공부해보려 한다. 오늘의 아이템은 생성자 대신에 인스턴스를 가져오는 방법인 정적 팩터리 메서드를 알아보려고 한다. 정적 팩터리 메서드의 장점과 단점에 대해 알아보고 적절히 나중에 사용해보자! 클라이언트가 클래스의 인스턴스를 얻는 전통적인 수단은 public 생성자다. 하지만 프로그래머가 꼭 기억해야 할 기법이 있다. 그 클래스의 인스턴스를 반환하는 클래스의 생성자와 별도로 정적 팩터리 메서드(static factory method)를 제공하는 것이다. 아래는 Boolean에서 가져온 예이다. public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } 장점 1..