Effective Java - Item 3
β μ±κΈν΄(singleton)
κ°μ²΄μ μ μΌμ±μ 보μ₯νκΈ° μν΄μ μΈμ€ν΄μ€λ₯Ό μ€μ§ νλλ§ μμ±ν μ μλ ν¨ν΄μ μλ―Ένλ€.
μΌλ°μ μΌλ‘ μ±κΈν΄ κ°μ²΄μ λν μ°Έμ‘°λ₯Ό public static νλλ public static λ©μλλ‘ λ ΈμΆνκΈ° λλ¬Έμ μ΄λμμλ μ±κΈν΄ κ°μ²΄ μ κ·Όμ΄ κ°λ₯νλ€.
μ±κΈν΄ ν¨ν΄μ νμ©νλ©΄ κ°μ²΄λ₯Ό μ¬μ¬μ© ν μ μκΈ° λλ¬Έμ λ©λͺ¨λ¦¬ μ¬μ© λλΉλ₯Ό λ§μ μ μκ³ μ μ κ°μ²΄μ΄κΈ° λλ¬Έμ λ€λ₯Έ κ°μ²΄μλ μμ‘°λ‘κ² κ³΅μ κ° κ°λ₯νλ€.
λ³΄ν΅ λ κ°μ§ λ°©λ²μ μ¬μ©νμ¬ μ±κΈν΄μ μμ±νλ€. 첫 λ²μ§Έλ public static λ©€λ²λ₯Ό finalλ‘ μ μΈνμ¬ μμ±νλ λ°©λ²μ΄λ€. λν μΈλΆμμλ μμ±μλ₯Ό ν΅ν΄ κ°μ²΄λ₯Ό μμ±ν μ μλλ‘ μ κ·Ό κΆνμ privateλ‘ μ μΈν΄μΌνλ€.
public static final νλ
1 2 3 4
public class Singleton { public static final Singleton INSTANCE = new Singleton(); private Singleton() {} }
β ν΄λμ€ μμ±μμ μΈμ€ν΄μ€λ₯Ό λ± ν λ² μμ±νλ€.
ν΄λΉ λ°©λ²μ ν΄λμ€κ° μ±κΈν΄μμ λͺ ννκ² μ μ μκ³ κ°κ²°νκ² ννν μ μλ€λ μ₯μ μ κ°μ§κ³ μλ€.
λ€λ§, 리νλ μ APIλ₯Ό μ¬μ©νμ¬ μμΈμ μΌλ‘ κ°μ λ‘ μμ±μλ₯Ό μμ±ν μ μλ λ°©λ²μ΄ μ‘΄μ¬νκΈ° λλ¬Έμ μ΄λ₯Ό μ£Όμνμ¬ μ½λλ₯Ό μμ±ν΄μΌ νλ€.
π 리νλ μ APIλ₯Ό μ¬μ©νμ¬ μμ±μλ₯Ό νΈμΆν κ²½μ°
- μ½λ
1 2 3 4 5 6 7 8 9 10 11 12 13
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class SingletonReflect { public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Constructor<Singleton> declaredConstructor = Singleton.class.getDeclaredConstructor(); declaredConstructor.setAccessible(true); Singleton singleton = declaredConstructor.newInstance(); } }
β
setAccessible(boolean)
λ©μλλ₯Ό μ¬μ©νμ¬ Singleton ν΄λμ€μ private μμ±μμ μ κ·Όμ΄ κ°λ₯νλ€.1 2 3 4 5 6 7 8 9 10 11
public class Singleton { public static final Singleton INSTANCE = new Singleton(); private Singleton() { if(INSTANCE != null) { throw new UnsupportedOperationException("μμ±μλ₯Ό νΈμΆν μ μμ΅λλ€."); } } }
β μμΈλ₯Ό μ¬μ©νμ¬ μΈμ€ν΄μ€κ° μ‘΄μ¬ν κ²½μ° μμ±μ νΈμΆ λΆκ°νλλ‘ λ§λλ€.
λ λ²μ§Έλ μμ±μλ privateλ‘ μ μΈνκ³ μ μ ν©ν 리 λ©μλλ₯Ό νμ©νλ λ°©λ²μ΄λ€.
- μ½λ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {
private static Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
if(INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
β ν΄λμ€ μμ±μμ μΈμ€ν΄μ€λ₯Ό λ± νλ²λ§ μμ±νλ€. getInstance()
λ©μλλ₯Ό μ¬μ©νλ κ²½μ°μ μ΄λ―Έ μ‘΄μ¬νλ μΈμ€ν΄μ€λ₯Ό λ°νν΄μ£Όμ΄ νμ κ°μ κ°μ²΄μ μ°Έμ‘°λ₯Ό λ°ννλ€.
μ μ ν©ν 리 λ©μλλ₯Ό νμ©νλ€λ©΄ μ±κΈν΄μ΄ μλλλ‘ νκ³ μΆμ λμλ APIλ₯Ό λ³κ²½νμ§ μκ³ λ μ½κ² λ€λ₯Έ κ°μ²΄λ₯Ό λ°ννλλ‘ λ³κ²½ν μ μλ€. λν λ©μλ μ°Έμ‘°λ₯Ό 곡κΈμλ‘ μ¬μ©ν μ μκ³ (Singleton::getInstance), μ μ ν©ν 리λ₯Ό μ λ€λ¦ μ±κΈν΄ ν©ν λ¦¬λ‘ λ§λ€ μ μλ€.
βμ λ€λ¦ μ±κΈν΄ ν©ν 리
μ λ€λ¦μΌλ‘ νμ μ€μ κ°λ₯ν μΈμ€ν΄μ€λ₯Ό λ§λ€μ΄λκ³ , λ°ν μμ μ λ€λ¦μΌλ‘ λ°μ νμ μ μ΄μ©ν΄ νμ μ κ²°μ νλ κ²μ΄λ€.
ν΄λΉ λ°©λ²λ μμ 리νλ μ APIλ₯Ό μ¬μ©νμ¬ κ°μ λ‘ μΈμ€ν΄μ€λ₯Ό μμ±ν μ μκΈ° λλ¬Έμ μ£Όμκ° νμνλ€.
public static νλλ μ μ ν©ν 리 λ©μλλ₯Ό νμ©νμ¬ μμ±ν μ±κΈν΄ ν΄λμ€λ₯Ό μ§λ ¬ννλ €λ©΄ λ¨μν Serializableμ ꡬννκ³ μ μΈνλ κ²λ§μΌλ‘λ λΆμ‘±νλ€. λͺ¨λ μΈμ€ν΄μ€ νλλ₯Ό μΌμμ (transient)μ΄λΌκ³ μ μΈνκ³ ReadResolve
λ©μλλ₯Ό μ 곡ν΄μΌνλ€. κ·Έλ μ§ μμΌλ©΄ μμ§λ ¬νμ μλ‘μ΄ μΈμ€ν΄μ€κ° μμ±λκΈ° λλ¬Έμ΄λ€.
λ§μ§λ§μΌλ‘, Effective Javaμμ μ±κΈν΄ ν¨ν΄μ μμ±νλλ° κ°μ₯ μ΄μμ μΈ λ°©λ²μΌλ‘ μλ¦¬κ³ μλ Enumμ νμ©νμ¬ μμκ° νλμΈ μ΄κ±° νμ μ μ μΈνλ λ°©λ²μ΄ μ‘΄μ¬νλ€.
1
2
3
public enum SingletonEnum {
INSTANCE;
}
β Enum
ν΄λμ€μ²λΌ 보μ΄κ² νλ μμμ΄λ©°, μλ‘ κ΄λ ¨μλ μμλ€λΌλ¦¬ λͺ¨μ μμλ€μ μ μν μ μλ€.
ν΄λΉ λ°©λ²μ κ°κ²°νκ² μμ±ν μ μμλΏλλ¬ μ΄λ ν λ°©μμμλ μΈμ€ν΄μ€κ° μΆκ°λ‘ μμ±λλ κ²μ λ§μ μ μλ€. λ μ§λ ¬νλ₯Ό μν΄ μΆκ°μ μΈ μ½λλ₯Ό μμ±ν νμκ° μκΈ° λλ¬Έμ μ±κΈν΄ κ°μ²΄λ₯Ό μμ±ν λμλ Enumμ νμ©νλ λ°©λ²μ κ°μ₯ μ’μ λ°©λ²μ΄λΌκ³ λ§ν μ μλ€.