목록이펙티브자바 (88)
도당탕탕
Finalizer란? Object 클래스의 메소드 중 하나로써, Garbage Collection이 수행될때 호출되는 메소드. 주로 자원을 해제하기 위해서 사용된다. ( Java 9에서는 deprecated됨 ) public class FinalizerTest extends Object { @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("finalizer is called!"); } } Cleaner란? Java 9부터 생겨났고 수거대상이 되는 객체를 Cleaner 의 register함수로 등록한다. 아래와 같이 수거대상이 되는 State 객체에 대한 정리 작업이 run() 함수에서 수행..
자바는 C와 C++과 다르게, 가비지 컬렉터에서 다 쓴 객체를 알아서 회수해 간다. 즉 메모리 관리를 따로 할 필요가 없어 프로그래머의 삶이 훨씬 편안해진다. 그렇다고 메모리 관리를 아예 신경쓰지 않아도 된다고 오해 할 수 있는데, 절대 그런 오해를 하면 안된다. 다음 코드를 보면 Memory leak - Stack Code public class Stack { private Obejct[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Obje..
불필요한 객체생성의 예시 String s = new String("bikini"); // 잘못된 사용의 예, "bikini" 자체가 String 객체를 생성함. String s = "bikini"; // 옳은 사용의 예 String s = new String("bikini") 처럼 사용하면 실행될때마다 String 객체가 새로 생성된다. 반면 String s = "bikini" 로 사용하면 같은 문자열에 대해서는 하나의 JVM안에서 재사용된다. Static factory method로 불필요한 객체 생성 피하기 다음 코드는 올바른 로마 숫자 표기법인지 검사하는 함수이다. static boolean isRomanNumeral(String s) { return s.matches("^(?=.)M*(C[MD]|..
Utility Class의 객체 생성을 막기 위해서는 private constructor를 선언해서 default constructor가 생기지 않도록 해야한다. public class UtiliyClass { private UtilityClass () { throw new AssertionError(); } } 물론 abstract class를 만듬으로써 객체 생성을 막을 수도 있지만 다음과 같은 문제가 있다. 다른 클래스가 이를 상속해서 객체를 생성할 수 있음 사용자도 상속을 해야하는 class로 오해 따라서 인스턴스화를 막으려거든 private 생성자를 선언해 사용하는 것이 좋다. 그러나 모든 코드는 트레이드 오프가 있듯 private 생성자에도 부작용도 있다. 바로 다른 클래스가 상속할 수 없다는..
클래스를 사용할 때 대부분의 클래스는 하나 이상의 자원을 사용할 것이다. 그중 Utility 클래스나 싱글톤 클래스를 만들어 자원을 효율적으로 사용할 수 있다. 하지만 이는 다음과 같은 문제가 발생할 수 있다. 다음 예를 들어 보자. Utility 클래스의 검시기 사전 public class SpellChecker { private static final Dictionary dictionary = ...; private SpellChecker() {} public static boolean isValid(String word) { ... } public static List suggestions(String typo) { ... } } Singleton 클래스의 검시기 사전 publicclass Spel..
싱글톤 패턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 즉 함수와 같은 무상태 객체나 설계상 유일해야 하는 시스템 컴포넌트를 들 수 있다. 싱글톤 패턴으로 클래스 오브젝트가 만들어지면 어플리케이션 내에서 전역으로 해당 오브젝트를 사용할 수 있다. 하지만 싱글턴 패턴은 다음과 같은 단점이 있다. 바로 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기가 어려워 질수 있다는 것이다. 싱글톤이 인터페이스로 정의해서 만든 것이 아니라면 Mock 으로 대체해 테스트 하기가 어렵기 때문이다. 물론 테스트가 아예 안되는 것은 아니다. PowerMock같은 도구를 통해 정적 메소드를 테스트 하게 할 수 있고 Mockito 3.4.0 버전에서는 정적 메소드를 지원해 준다고 한다. 싱글톤 패..
생성자나 정적 팩터리 메소드에서는 매개변수가 많을 경우 개발자가 대응하기 어렵다는 제약이 있다. 이렇게 말로 표현하면 와닿지 않을 수 있다. 그래서 밑에 비디오 클래스를 예를 들어보려고 한다. 비디오 클래스에는 다음과 같은 필드가 존재한다. 비디오 아이디 (필수) 비디오 타이틀 (필수) 비디오 설명 (선택) 비디오 등록 날짜 (선택) 비디오 파일 (필수) 비디오 썸네일 이미지 (선택) 단 필수로 받는 필드는 비디오 아이디, 타이틀, 비디오 파일이고, 선택으로 받는 필드는 비디오 등록 날짜, 썸네일 이미지, 설명이라고 정의 하자. 점층적 생성자 패턴 프로그래머들은 점층적 생성자 패턴을 즐겨 사용할 것이다. 필수 매개변수만 받는 생성자, 필수 매개변수와 선택 매개변수 1개를 받는 생성자, 선택 매개변수 2개..
클라이언트가 클래스의 인스턴스를 얻는 수단은 2가지의 방법이 있다. public 생성자로 인스턴스를 제공하는 방법 생성자와 별도로 정적 팩토리 메서드로 제공하는 방법 - 클래스 인스턴스를 반환하는 단순한 정적 메소드 public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } 2번째 방법은 public 생성자 대신 정적으로 생성자를 제공할 수 있다. 이 방식에는 장점과 단점이 모두 존재한다. 이 장단점을 지금 부터 알아보려고 한다. 정적 팩토리 메소드의 장점 이름을 가질 수 있다. 생성자에 넘기는 매개변수와 생성자 자체만으로는 반환될 객체의 특성을 제대로 설명하지 못한다. 하지만 정적 팩토리 메소드를 사용하면 반..