본문 바로가기

책읽고 정리/Effective Java8

[Effective Java 3/E] 아이템9. try-finally보다는 try-with-resources를 사용하라 자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다.(InputStream, OutputStream, java.sql.Connection 등) 자원 닫기는 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어지기도 한다. 안전망으로 fianlizer를 활용하기도 하지만 믿을만하지 못하다.(아이템 8) 전통적인 자원 닫힘 보장 수단 : try-finally 단점 자원이 둘 이상이면 코드가 지저분해진다. 두 번째 예외가 첫 번째 예외를 집어삼켜 버려 스택 추적 내역에 첫 번째 예외 정보는 남지 않게 되고, 디버깅을 어렵게 한다. 아래 firstLineOfFile 메서드의 br.readLine()에서 예외가 발생하고, br.close() 실패하면 두 번째 예외가 첫 번째 예외를 삼켜버린다.. 2021. 6. 22.
[Effective Java 3/E] 아이템7. 다 쓴 객체 참조를 해제하라 가비지 컬렉터가 다 쓴 객체를 알아서 회수해간다고 메모리 관리에 신경 쓰지 않아도 된다는 것은 아니다. 메모리 누수의 예 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.. 2021. 6. 22.
[Effective Java 3/E] 아이템6. 불필요한 객체 생성을 피하라 똑같은 기능의 객체를 매번 생성하는 것보다 객체 하나를 재사용하는 편이 나은 경우가 많다. 불변 객체는 언제든 재사용할 수 있다. String s = new String("bikini"); //따라 하지 말 것!생성자로 문자열을 만들면 매번 새로운 String 인스턴스를 생성(Heap 영역에 할당). String s = "bikini";리터럴로 문자열을 만들면 String Constatnc Pool에 할당되어 같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용하는 것이 보장된다. https://madplay.github.io/post/java-string-literal-vs-string-object 정적 팩터리 메서드 생성자 대신 정적 팩터리 메서드를 사용해 불필요한 객체 생성을 피할 수 있다.. 2021. 6. 10.
[Effective Java 3/E] 아이템5. 자원을 직접 명시하지 않고 의존 객체 주입을 사용하라 사용하는 자원에 따라 동작이 달라지는 클래스는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. 사전(Dictionary)에 의존하는 맞춤법 검사기(Spell Checker)를 예로 들어보자. 사전은 언어별로 따로 있고, 테스트 용도 사전이 필요할 수도 있다. 하지만 두 방식 모두 하나의 사전만 사용할 수 있다. final 한정자를 제거하고 다른 사전으로 교체할 수도 있지만, 오류를 내기 쉬우며 멀티 스레드 환경에서는 사용할 수 없다. //정적 유틸리티를 잘못 사용한 예 - 유연하지 않고 테스트하기 어렵다. public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() {} //객체 생성 .. 2021. 5. 29.
[Effective Java 3/E] 아이템4. 인스턴스화를 막으려거든 private 생성자를 사용하라 단순히 정적 메서드와 정적 필드만을 담은 클래스를 만들어야 할 때가 있다. 예를 들어 java.lang.Math, java.util.Arrays와 같이 기본 타입 값이나 배열 관련 메서드들을 모아둘 때 java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(혹은 팩터리)를 모아 놓을 때. -> 자바 8부터는 인터페이스에 넣을 수 있다. final 클래스와 관련한 메서드들을 모아놓을 때(final 클래스를 상속할 수 없기 때문에) 문제점 예시와 같이 정적 멤버만을 가지고있는 유틸리티 클래스는 인스턴스로 만들어 사용하려고 설계한 클래스가 아니다. 생성자를 명시하지 않으면 컴파일러가 매개변수가 없는 public 생성자를 자동으로 생성해주기 때문에, 인스턴스화가 가능.. 2021. 5. 25.
[Effective Java 3/E] 아이템3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 싱글턴이란? 싱글턴(Singleton) 이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기 어려워질 수 있다. 인터페이스를 구현한 싱글턴이 아니라면 Mock 구현으로 대체할 수 없기 때문에 싱글턴 생성 방식 1. public static final 필드 private 생성자는 public static final 필드인 Elvis.INSTANCE를 초기화할 때 딱 한번 호출 예외 : 권한이 있는 클라이언트는 리플렉션 API인 AccessibleObject.setAccessible을 사용해 private 생성자를 호출할 수 있다. 생성자에서 두번째 객체가 생성되려 할 때 예외를 던지게 하면 이러한 공격을 방어할 수 있다. public.. 2021. 5. 24.