본 게시글은 혼자 공부하는 자바 (저자 : 신용권)의 책과 유튜브 영상을 참고하였고, 개인적으로 정리하는 글임을 알립니다.
싱글톤
프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있다.
단 하나만 생성된다고 해서 이 객체를 싱글톤이라고 한다.
싱글톤을 만들려면 클래스 외부에서 new 연산자로 생성자 호출을 막아야 한다.
생성자를 외부에서 호출할 수 없도록 하려면 private 접근 제한자를 붙여주면 된다.
생성자를 private으로 접근을 제한했더라도, 클래스 내부에서는 생성자 호출이 가능하다.
싱글톤을 만드는 방법은 다음과 같다.
- 정적 필드로 자신 타입의 객체를 생성하고 private로 외부 접근을 제한한다.
- 생성자를 private를 이용하여 외부 접근을 제한한다.
- 정적 메소드를 선언하고 정적 필드에서 참조하고 있는 자신의 객체를 리턴해준다.
package TestPakage;
public class Single {
//정적 필드
private static Single obj = new Single();
//생성자
private Single() {
}
//정적 메소드
static Single getInstance() {
return obj;
}
}
위 코드 처럼 싱글톤 객체를 만들면, 외부에서 객체를 얻는 유일한 방법은 getInstance() 메소드를 호출하는 방법이다.
package TestPakage;
public class Test {
public static void main(String[] args) {
Singleton obj1 = new Singleton(); //컴파일 에러
Singleton obj2 = new Singleton(); //컴파일 에러
Single a = Single.getInstance();
Single b = Single.getInstance();
if(a == b) {
System.out.println("동일 객체");
} else {
System.out.println("다른 객체");
}
}
}
/*
동일 객체
*/
final 필드와 상수
final 필드
final 필드는 초기값이 저장되면 최종적인 값이 되어서 프로그램 실행 도중에 수정할 수 없다.
final 필드의 초기값을 줄 수 있는 방법은 두 가지 이다.
- 필드 선언 시에 주는 방법
- 생성자에서 주는 방법
생성자에서 초기값을 주는 경우에, 생성자는 final 필드의 최종 초기화를 마쳐야 하는데 만약 초기화되지 않은 final 필드를 그대로 남겨두면 컴파일 에러가 발생한다.
Person.java
package TestPakage;
public class Person {
final String nation = "Korea";
final String ssn;
String name;
public Person(String ssn, String name) {
this.ssn = ssn;
this.name = name;
}
}
Test.java
package TestPakage;
public class Test {
public static void main(String[] args) {
Person p1 = new Person("123456-1234567", "홍길동");
System.out.println(p1.nation);
System.out.println(p1.ssn);
System.out.println(p1.name);
p1.nation = "ReBugs"; //컴파일 오류, final 필드는 수정 불가능
p1.ssn = "654321-7654321"; //컴파일 오류, final 필드는 수정 불가능
p1.name = "아무 이름"; //일반 변수는 수정 가능
}
}
/*
Korea
123456-1234567
홍길동
*/
상수
불변의 값을 상수(static final)라고 부른다.
final 필드는 한 번 초기화되면 수정할 수 없는 필드라고 했다. 그렇다면 final 필드를 상수라고 불러도 되지 않을까?
final 필드를 상수라고 부르진 않는다. 왜냐하면 불변의 값은 객체마다 저장할 필요가 없는 공용성을 띠고 있으며, 여러 가지 값으로 초기화될 수 없기 때문이다.
final 필드는 객체마다 저장되고, 생성자의 매개값을 통해서 여러 가지 값을 가질 수 있기 때문에 상수가 될 수 없다.
상수는 static이면서 final이어야 한다. static final 필드는 객체마다 존재하지 않고 클래스에만 존재한다. 그리고 한 번 초기값이 저장되면 변경할 수 없다.
상수의 초기값을 줄 수 있는 방법은 두 가지 이다.
- 필드 선언 시에 주는 방법
- 정적 블록에서 주는 방법
상수 이름은 모두 대문자로 작성하는 것이 관례이고, 만약 서로 다른 단어가 혼합된 이름이라면 언더바(_)로 단어들을 연결한다.
Earth.java
package TestPakage;
public class Earth {
static final double EARTH_RADIUS = 6400;
static final double EARTH_AREA;
static{
EARTH_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
}
}
Test.java
package TestPakage;
public class Test {
public static void main(String[] args) {
System.out.println("지구 반지름 : " + Earth.EARTH_RADIUS + " km");
System.out.println("지구 표면적 : " + Earth.EARTH_AREA + " km^2");
}
}
/*
지구 반지름 : 6400.0 km
지구 표면적 : 5.147185403641517E8 km^2
*/
'Language > Java' 카테고리의 다른 글
[JAVA] 접근 제한자(Access Modifier) (0) | 2023.01.06 |
---|---|
[JAVA] 패키지(Package) (0) | 2023.01.05 |
[JAVA] 인스턴스 멤버와 정적 멤버 (0) | 2023.01.03 |
[JAVA] 메소드(Method) (0) | 2023.01.02 |
[JAVA] 생성자(Constructor) (0) | 2023.01.01 |