본문 바로가기

프로그래밍/Java 프로그래밍

자바 싱글톤과 상수

싱글톤


가끔 전체 프로그램에서 단 하나의 객체만 만들도록 보장해햐 하는 경우는 있습니다. 단 하나만 생성된다고 해서 이 객체를 싱글톤(Singleton)이라고 합니다.


싱글톤을 만들려면 클래스 외부에서 new 연산자로 생성자를 호출할 수 없도록 막아야합니다. 생성자를 호출한 만큼 객체가 생성되기 때문입니다. 생성자를 외부에서 호출할 수 없도록 하려면 생성자 앞에 private 접근 제한자를 붙여주면 됩니다. 접근제한자는 다음번에 포스팅하니까 자세히 사펴보시고 지금은 단순히 private 접근 제한자를 붙인다는 것만 알아주십시요. private은 말그대로 사적인 거라 다른 곳에서는 접근이 안되고 자기 자신에서만 접근이 됩니다. 그러므로 밖에서는 생성자에 접근이 안되므로 밖에서 new 를 사용할 수 없습니다. 그래도 클래스라면 사용하기 위해 객체를 생성해야하기때문에 생성자 실행이 필수인데 이것을 위해 자신의 타입인 정정 필드를 하나 선언하고 자신의 객체를 생성해 초기화합니다. 말로 설명하는 것보다 예제를 들어 살펴보도록 하겠습니다.




위의 프로그램은 싱글톤 패턴을 적용시키는 전형적인 예제입니다. 외부에서 new 연산자를 이용해서 새로운 객체를 생성하는 것을 막기위해 private으로 Singleton() 생성자를 선언하고 클래스 내부에서 new를 사용해서 static 변수인 singleton에 저장하였습니다. singleton 변수는 클래스 변수이며 static으로 지정했기 때문에 객체를 생성하지 않고서도 외부에서 호출이 가능합니다. getInstance 메소드를 사용해서 내부에서 한번만 생성한 singleton 객체를 반환해서 하나의 객체를 지정할 수 있도록 했습니다. 두번째 프로그램에서 라인 6과 라인 7일 주석으로 막은 것은 컴파일 오류때문입니다. 이는 Singleton() 생성자가 private이므로 외부에서 호출했을 경우 오류가 발생하기 때문입니다. 그래서 라인 10과 11 처럼 getInstance() 메소드를 사용해서 객체를 지정해야만 합니다. obj1과 obj2는 같은 주소를 가지고 있습니다. 그래서 "같은 Singleton 객체입니다."라는 결과를 출력하게 됩니다.



final 필드와 상수


final 필드


final은 최종적이라는 뜻을 가지고 있습니다. 그렇다면 final 필드는 최종 필드라는 뜻인데 이것은 이 필드의 값이 더 이상 변할 수 없다는 뜻입니다. 그래서 초기값이 저장되면 프로그램 실행중에 더 이상 바꿀 수 없다는 뜻이됩니다. final 필드의 초기값을 줄 수 있는 경우는 두 가지 밖에 없습니다.

1. 필드 선언 시에 초기화시키는 방법

2. 생성자에서 초기화시키는 방법





위의 프로그램에서 nation과 ssn은 final 필드입니다. 그렇기때문에 nation은 선언에서 초기화하였고 ssn은 생성자에서 초기화하였습니다. 일단 초기화한 후에는 변경이 될 수 없습니다. 그래서 두번째 프로그램의 라인11과 라인 12를 주석으로 처리하였습니다. 왜냐하면 nation과 ssn을 바꾸려고 했기 때문입니다. 이렇듯 한번 초기화한 후 프로그램 상에서 바뀔 필요가 없는 필드가 존재한다면 final 변수로 선언하는 것이 좋습니다.


상수


일반적으로 불변의 값을 상수라고 부릅니다. 이는 변수와는 상대되는 개념입니다. 우리는 프로그램에서 값을 저장하고 사용하기 위해 변수를 사용합니다. 상수값은 불변의 값을 지정할 때 자주 쓰입니다. 예를들면 수학의 원주율 파이 값을 나타낼 때 쓰입니다. final 필드는 한번 초기화되면 수정할 수 없는 필드라고 했습니다. 그렇다면 final 필드를 상수라고 불러도 될까요? 하지만 final 필드는 상수라고 부르지 않습니다. 왜냐하면 불변의 값은 객체마다 저장할 필요가 없는 공용성을 띠고 있으며, 여러 가지 값으로 초기화될 수 없기 때문입니다. final 필드는 객체마다 저장되고 객체마다 다른 값을 가질 수 있으므로 상수라고 할 수 없습니다. 상수는 static 이면서 final이어야 합니다. static final 필드는 객체마다 존재하지 않고 클래스에만 존재합니다. 그리고 한번 초기값이 저장되면 변경할 수 없습니다. 상수 이름은 모두 대문자로 작성하는 것이 관례입니다. 만약 서로 다른 단어의 혼합된 이름이라면 언더바(_)로 단어를 연결해줍니다.




위의 프로그램에서 우리는 상수를 사용했습니다. EARTH_RADIUS와 EARTH_AREA가 상수입니다. 관례대로 모두 대문자를 사용했으며 서로 다른 단어는 언더바(_)를 사용하여 결합했습니다. 위의 예제에서 Math.PI를 사용했는데 이는 Math라는 클래스에 있는 상수 PI를 가져온 것입니다. 이는 자바에서 사용자가 사용할 수 있도록 만든 많은 메소드와 필드가 있습니다. 이것을 이용하는 방법은 API를 배우면서 알게 될 것이고 API를 얼마나 잘 찾아서 잘 사용하느냐가 프로그래밍에 중요한 요소가 될 수 있습니다.