티스토리 뷰

싱글턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스

 

싱글턴을 만드는 3가지 방법

 

1. public static final 방식

public class Singleton {
    public static final Singleton INSTANCE = new Singleton();
    
    private Singleton() {}
    public void singletonMethod() {}
    
}

private 생성자는 public static final 필드의 Singleton.INSTANCE를 초기화 할 때 한 번만 호출

public이나 protected 생성작 없으므로 클래스가 초기화 될 때 만들어진 인스턴스가 전체 시스템에서 하나뿐임이 보장

예외적으로 권한이 있는 클라이언트는 AccessibleObject.setAccessible을 이용해 private 생성자를 호출 할 수 있음

 

2. 정적 팩터리 방식

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}
    public static Singleton getInstance() {
        return INSTANCE;
    }
    public void singletonMethod() {}
}

api를 변경하지 않고도 싱글턴이 아니게 변경할 수 있다.

기타 다른 장점은 뒤에서..(아이템 30, 43, 44)

3. 열거 타입 방식

public enum Singleton {
    INSTANCE;

    public void singletonMethod() {}
}

public 필드 방식과 비슷하지만, 더 간결하고, 추가 노력 없이 직렬화할 수 있다.

리플렉션 공격에서도 제 2의 인스턴스가 생기는 일을 막아준다.

public class Singleton {
    public static final Singleton INSTANCE = new Singleton();

    private Singleton() {

    }
    public static Singleton getInstance() {
        return INSTANCE;
    }
    public void singletonMethod() {
        System.out.println("singletonMethod");
    }

    public static void main(String[] args) {
       // Singleton singleton = new Singleton();
        Class<? extends Singleton> cl = null;
        try {
            cl = (Class<? extends Singleton>) Class.forName("Singleton");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Constructor<? extends Singleton> constructor = null;
        try {
            constructor = cl.getDeclaredConstructor();
            Singleton singleton = constructor.newInstance();
            singleton.singletonMethod();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

단, 만들려는 싱글턴이 Enum외의 클래스를 상속해야 한다면 이방법은 사용할 수 없다.

 

+ 클래스안에서 실수로 생성자를 호출하지 안하도록 막기

public class Singleton {
    public static final Singleton INSTANCE = new Singleton();

    private Singleton() {
        if (INSTANCE !=null)
            throw new AssertionError();
    }
    public static Singleton getInstance() {
        return INSTANCE;
    }
    public void singletonMethod() {}

    public static void main(String[] args) {
        Singleton singleton = new Singleton();
    }
}

'개발 > Java' 카테고리의 다른 글

자바 tcp/ip 소켓통신  (0) 2021.02.06
Effective Java 3/E - 정적 팩터리 메서드  (0) 2021.01.14
자바 스트림 -2  (0) 2021.01.01
자바 스트림 -1  (0) 2020.12.26
자바 람다식  (0) 2020.12.19
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함