전체 글

기록하며 공부하는 기술 블로그
Study/이펙티브 자바

[Effective Java 3E] try-finally 보다는 try-with-resources를 사용하라

💥 개요 자바 라이브러리에는 close 메서드를 호출, 명시적으로 close를 해야하는 경우가 많습니다. InputStream, OutputStream, Connection 등이 대표적으로 있습니다. close를 하지 않으면 예측할 수 없는 성능 문제로 이어지기도 합니다. 이런 자원 중 상당수가 안전망으로 finalizer를 활용하고 있긴 하지만 그리 믿음직하지 못합니다. 전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 예외가 발생하거나, 메서드에서 반환하는 경우를 포함해서 try-finally가 사용됐습니다. 위 예시를 보면 왼쪽에서 하나의 자원을 사용하는 경우는 그나마 괜찮지만, 2개 이상의 자원을 close해야 하는 경우에는 가독성이 좋지않고, 코드가 지저분해 보입니다. 그리고 기기에 문제가 생긴..

Study/이펙티브 자바

[Effective Java 3E] finalizer와 cleaner 사용을 피하라

💥 개요 자바에서는 2가지 객체 소멸자를 제공합니다. 그중 finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요합니다.(앞으로 개발하면서 쓸 일이 없을지도...) 심지어 자바9에서 deprecated API 로 지정되었고, 그 대안으로 cleaner를 제시했지만, cleaner 역시 위험하고, 예측할 수 없고, 느리고, 불필요합니다. 🩻 문제 언제 수행될지 모른다 finalizer와 cleaner는 즉시 수행된다는 보장이 없습니다. 객체에 접근할 수 없게 된 후 finalizer와 cleaner로는 제때 실행되야 하는 작업은 절대 할 수없습니다.(파일, db처럼 사용 후 즉시 반납되어야 하는 자원에 절대 사용X) finalizer와 cleaner가 언제 수행될지는 전적으로 ..

Study/이펙티브 자바

[Effective Java 3E] 다 쓴 객체 참조를 해제하라

💥 개요 C나 C++처럼 메모리를 직접 관리해야 하는 언어를 쓰다, 자바를 사용하면 가비지 컬렉터로 인해 훨씬 편안하게 메모리를 관리 할 수 있습니다. 다 쓴 객체를 GC가 알아서 회수해가니까 이런일이 가능합니다. 하지만 메모리 관리를 더 이상 하지 않아도 된다고 오해할 수 있는데, 절대 사실이 아닙니다. 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) { ens..

Study/이펙티브 자바

[Effective Java 3E] 불필요한 객체 생성을 피하라

💥 개요 똑같은 기능의 객체를 매번 생성하기 보다, 객체 하나를 재 사용하는게 더 나을때가 많습니다. 재사용은 빠르고 세련됐고 불변 객체는 언제든 재사용이 가능합니다. 하지만 아래와 같은 코드는 엄청난 문제가 발생합니다. String s = new String("bikini"); 이 문장은 실행될 때마다 String 인스턴스를 새로 만듭니다. 하지만 아래의 코드는 새로운 인스턴스를 만드는 대신 하나의 String 인스턴스를 사용합니다. 자바는 문자열을 직접 할당할 시 문자열 상수 풀 내부에 모든값을 저장하기 때문에 같은 가상 머신 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용함이 보장됩니다. String s="bikini"; 👍 정적 팩터리를 제공하는 불변 클래스 정적 팩터..

Study/이펙티브 자바

[Effective Java 3E] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

💥 개요 많은 클래스가 하나 이상의 자원에 의존합니다. 가령 맞춤법 검사기는 사전(dic-tionary)에 의존하는데, 이런 클래스를 정적 유틸리티 클래스로 구현한 모습을 드물지 않게 볼 수 있습니다. 1. 정적 유틸리티 클래스 public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() {} public static boolean isVaild(String word) {...} public static List suggestions(String typo) {...} } 2. 싱글턴 public class SpellChecker { private final Lexicon dictionary ..

Study/이펙티브 자바

[Effective Java 3E] 인스턴스화를 막으려거든 private 생성자를 사용하라

💥 개요 정적 메서드와 정적 필드만을 담은 클래스는 객체지향적이라고 볼 수 없습니다. 하지만 분명 쓰임새가 있는데, 기본 타입 값(java.util.Arrays)이나 java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아 놓을 수 있습니다. 자바 8부터는 이런 메서드를 인터페이스에 넣을 수 있게 되었습니다. 또한 final 클래스와 관련된 메서드들을 모아놓을 때도 사용합니다. final 클래스를 상속해 하위 클래스에 메서드를 넣는건 불가능하기 때문입니다. 🩻 문제 정적 멤버만 담은 유틸 클래스는 instance로 만들어 쓰려한게 아닙니다. 하지만 문제는 생성자를 명시하지 않으면 컴파일러는 기본 생성자를 자동으로 만듭니다. 그리고 추상클래스로 만드는 방법..

Study/이펙티브 자바

[Effective Java 3E] private 생성자나 열거 타입으로 싱글턴임을 보증하라

💥 개요 싱글턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말합니다. 싱글턴의 전형적인 예시로 함수와 같은 무상태성(stateless) 객체나 설계상 유일해야 하는 시스템 컴포넌트를 들 수 있습니다. 그런데 클래스를 싱글턴으로 만들면 사용하는 클라이언트를 테스트하기가 어려워 질 수 있습니다. 타입을 인터페이스로 정의한 다음 그 인터페이스를 구현해서 만든 싱글턴이 아니라면 싱글턴 인스턴스를 mocking 할 수 없기 때문입니다. 💡싱글턴을 만드는 방식 우선 생성자를 private으로 감춰두고, 유일한 인스턴스에 접근할 수 있는 수단으로 public static 멤버를 하나 마련해둡니다. 1. public static 멤버가 final 필드인 방식 private 생성자는 public static 필..

Study/이펙티브 자바

[Effective Java 3E] 생성자에 매개변수가 많다면 빌더를 고려하라

💥 개요 정적 팩터리와 생성자에는 똑같은 제약이 하나 있습니다. 매개변수가 많은 경우 문제가 발생하는데, 만약 20개, 30개의 멤버 변수를 가지는 경우가 문제가 발생합니다. 물론 멤버변수가 모두 필수값이라면 클래스로 묶어 처리하는 방법도 있겠지만, 대부분의 경우 대다수의 값이 기본값(0, 혹은 DB에서 정의된 Default Value)이 포함되는 경우가 많이 발생하게 됩니다. 또한 선택적 매개변수를 받아야 하는 경우, 기존에는 원하는 매개변수의 개수에 따라 생성자나 정적 팩터리를 늘려야하는 경우가 발생합니다. 이 클래스의 인스턴스를 만들려면 원하는 매개변수를 모두 포함한 생성자 중 가장 짧은것을 골라 호출하면 됩니다. 하지만 이런 점층적 생성자 패턴은 위에 말한 것처럼 매개 변수의 개수가 늘어날수록 코..

mntdev
MNT_Dev