2021-06-18 강의록_싱글톤
싱글톤
싱글톤 객체 : 이 클래스로부터 힙 영역에 단 한 번만, 단 하나의 객체만 생성 가능.
힙에 있는 모든 객체가 공유할 용도로 쓰임. 대표적으로 환경설정.
환경설정 정보를 필드로 들고있는 싱글톤 객체가 있다.
이 설정 정보는 하나의 객체에만 있어야 함. 여러 객체에 있으면 내용이 모두 다를 수 있으니까.
단 하나의 객체만 존재해야 하며, 프로그램이 시작되어 종료될 때까지 살아 있어야 함. (=가비지컬렉터GC 작동 X)
가비지 객체
생성되어 아무도 사용하지 않으면 GC가 작동된다.
싱글톤 만드는 방법
-
외부에서 new 연산자로 생성자 호출할 수 없도록 막기
: private 접근제한자를 생성자 앞에 붙임 -
클래스 자신의 타입으로 정적 필드 선언
: 자신의 객체를 생성해 초기화.
private 접근 제한자 붙여 외부에서 필드 값 변경 불가하도록
//static 붙이면 clazz 소속이 됨. 한 번 메소드영역에 꽂힌 clazz 객체는 프로그램이 떨어질 때 까지 사라지지 않는다.
(gc는 힙 영역의 객체에만 해당) -
외부에서 호출할 수 있는 정적 메소드인 getInstance() 선언
: 정적 필드에서 참조하고 있는 자신의 객체 리턴
객체를 생성하지 않고 메소드를 호출해야 하므로 static 메소드로 선언!!!!!
(private으로 막아놨기 때문에 객체생성 X)
//외부에서 역시 접근 불가능하게 private 접근제한자(access modifier) 로 은닉화(캡슐화)
// 단 한 번 생성될 싱글톤 객체의 주소를 보관할 필드 선언 -------------------(2)
private static Singleton singleton = new Singleton();
/////////////////
//모든 쓰레드, 모든 객체에서 공유할 데이터를 보관할 필드를 선언
/////////////////
private int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
static {
log.debug(">>>>>> static initializer invoked.");
Singleton.singleton = new Singleton();
} //static initializer : JVM이 오직 단 한번만 호출되도록 보장하는 블록
//외부에서는 호출 불가능하게 private접근제한자로 은닉화(캡슐화)
private Singleton() { //외부에서 new연산자로 호출 못하도록 private으로 선언 ---------(1)
;;
} //default constrctor
//외부에서 언제든 호출 가능하도록 하려면, 객체생성 없이도 호출할 수 있도록 static 메소드로 선언
//싱글톤 객체이 주소를 보관하고 있는 필드의 값을, 언제든 필요로 하는 다른 객체에 줄 수 있도록
//정적 메소드를 선언 -------------------(3)
static Singleton getInstance() {
return singleton;
} //getInstance
배열(intArray)에 왜 static 키워드 붙이지 않는지?
->> 싱글톤은 공유(heap영역의 모든 객체들이 공유)되고, 보호되고 있는 하나의 상자.
이 상자 이미 private static으로 생성되어있고, 이 안에 데이터로서 배열(intArray)을 넣은 것.
Clazz객체로 만드는 의미가 아니다.
메소드 영역은 크기가 크지 않음. 이 안에 큰 배열을 넣는것은 위험하다. (VM 이 죽을 수 있다)
무엇보다 싱글톤객체는 '객체'임.
객체 안의 데이터는 '필드'로 존재.
이 '필드'는 '인스턴스 필드'임. >>객체 안에 존재하니까 당연
따라서 static 키워드 X
- Singleton 객체 테스트 1
public static void main(String[] args) {
/*
* Singleton obj1 = new Singleton(); //컴파일 에러
* Singleton obj2 = new Singleton(); //컴파일 에러
*/
//싱글톤 객체 레퍼런스 얻기
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
// 동등비교연산자를 참조변수에 수행할 때에는, 두 참조변수에 있는 주소값을 비교하는 것!
if (obj1 == obj2) {
log.info("같은 Singleton 객체 입니다.");
}else {
log.info("다른 Singleton 객체 입니다.");
} //if-else
}//main
->> 같은 객체임을 확인할 수 있다.
- Singleton 객체 테스트 2
public static void main(String[] args) {
/*
* Singleton obj1 = new Singleton(); //컴파일 에러
* Singleton obj2 = new Singleton(); //컴파일 에러
*/
for(int i=1; i<=10; i++) {
Singleton obj = Singleton.getInstance();
log.info(String.format("[%d] obj : [%s]", i, obj));
}//for
}//main
->> 레퍼런스 값 같음. (OID같다)
Author And Source
이 문제에 관하여(2021-06-18 강의록_싱글톤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@mindddi/2021-06-18-강의록싱글톤저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)