컴공댕이 공부일지
[ java를 자바라 ] static / 싱글톤 패턴 / final 본문
2023.05.08 EC.crew 정모
💙static
new로 생성하지 않는 객체/공유변수에 사용하는 키워드
메모리 static 영역에 만들어져 공유된다!
쉽게 말해 다 같이같이 쓰는 건 딱 한번만 생성해두면 되니깐 쓰는 개념이다~
공기는 함께 공유해서 쓰는 자원이니 굳이 공기를 각각의 객체로 공기1, 공기2 이럴 필요가 없다.
아래 예제를 보면 static을 통한 공유를 더 잘 이해할 수 있다.
🔎 static의 공유적 특성
[ static 사용 x ]
public class staticEx {
int num = 0;
staticEx() {
this.num++;
System.out.println(this.num);
}
}
public class Sample {
public static void main(String[] arts) {
staticEx s1 = new staticEx();
staticEx s2 = new staticEx();
}
}
>>>
1
1
각각의 객체에서 공유되지 않고, num이 각각 존재하므로 둘 다 1이 출력된다.
그런데 이 num 변수의 값이 공통적으로 쓰이는 값이라면? (ex. 홈페이지 방문자 수 등)
그러면 매번 저렇게 다른 객체로 생성된 필요 없이 하나로 공유해 쓰면 되는것이다!
공유하고 싶은 변수에 static을 붙여보자~ :)
[ static 사용 o ]
public class staticEx {
static int num = 0;
staticEx() {
num++;
System.out.println(num);
}
}
public class Sample {
public static void main(String[] arts) {
staticEx s1 = new staticEx();
staticEx s2 = new staticEx();
}
}
>>>
1
2
num 앞에 static을 붙였더니, num 값이 하나로 공유되기 때문에 1 2가 출력된다
🔎 static의 공간적 특성
non-static 멤버는 객체마다 별도로 존재해서 인스턴스 멤버라고 부르지만,
static 멤버들은 클래스 당 하나만 생성되며, 객체 내부가 아닌 별도의 공간(클래스 코드가 적재되는 공간)에 생성된다. 클래스 멤버(=정적 변수) 라고 부른다.
ㅡ
또한, static 키워드를 붙이면 자바는 메모리 할당을 딱 한번만 하게 되어 메모리 사용에 이점이 있다.
일반적인 클래스는 static 영역에 생성되고, new를 통해 생성한 객체는 heap영역에 생성됨.
힙 영역의 메모리는 Garbage collector를 통해 수시로 관리받음.
그런데 static 영역에 할당된 메모리는 가비지 콜랙터의 관리 영역 밖이라,
프로그램 종료시까지 메모리가 할당된 채로 존재하므로 자주 사용하면 시스템 퍼포먼스에 악영향을 줌.
🔎 static의 시간적 특성
static 멤버들은 클래스가 로딩될 때 static 공간에 할당됨.
non-static 멤버
객체 생성 시 멤버가 생성
- 객체가 생겨야 멤버도 생성될 수 있음
- 객체 생성 후에 멤버를 사용할 수 있음
- 객체가 사라지면 멤버도 사라짐
static 멤버
클래스 로딩 시 멤버 생성. 생성하지 않고 바로 사용가능.
- 객체가 생기기 전에 이미 생성
- 객체 생성 전에도 사용 가능
- 객체가 사라져도 멤버는 안사라짐
- 멤버는 프로그램 종료 시에 사라짐
[ 스태틱 메서드의 활용 : 조회수 카운팅 클래스 ]
public class Counter {
static int count = 0;
//static 안쓰면 에러! 아래 getCount는 스태틱 메서드.
//스태틱 메서드 안에서 스태틱 변수 아닌 객체 변수에는 접근할 수 없다!
Counter() {
count++;
System.out.println(count);
}
public static int getCount() {
return count;
}
}
public class Sample {
public static void main(String[] arts) {
Counter c1 = new Counter();
Counter c2 = new Counter();
System.out.println("조회수 얼마나 되지? ");
System.out.println(Counter.getCount());
//클래스를 이용해 스태틱 메서드 호출
}
}
>>>
1
2
조회수 얼마나 되지?
2
스태틱 메서드는 "클래스이름.메서드이름()" 으로
객체 생성없이 클래스를 통해 메서드를 직접 호출할 수 있다.
static의 활용
- 전역 변수와 전역 함수(전역 메소드) 만들 때
- 공유 멤버 작성할 때
어떤 객체가 단 한 개만 생성되야하는 객체라면? 싱글톤 객체로 구현한다.
💙싱글톤 패턴 (singleton pattern)
싱글톤은 단 하나의 객체만을 생성하게 강제하는 디자인 패턴이다.
즉, 클래스를 통해 생성할 수 있는 객체가 딱 하나.
접근 제한자 private을 활용해 외부에서 new 연산자로 생성자를 만들 수 없도록 함. ( 클래스 내부에서는 호출 가능! )
#1. private 정적 필드를 하나 선언해 객체 생성&초기화
#2. 외부에서 호출할 수 있는 정적 메소드 getInstance()를 선언하고 정적 필드의 객체를 리턴
( 외부에서 객체를 얻는 유일한 방법은 getInstance() 메소드를 호출하는 것! )
public class 하늘 {
//정적 필드 : 생성&초기화
private static 하늘 푸른하늘 = new 하늘();
//생성자
private 하늘() {}
//정적 메소드 : 외부에서 호출 가능! => 외부에서 객체를 얻는 유일한 방법~
static 하늘 getInstance() {
return 푸른하늘;
}
}
public class 하늘ex {
public static void main(String[] args) {
//하늘 a = new 하늘(); 이렇게 생성할 수 없어! 생성자가 private.
하늘 a = 하늘.getInstance();
하늘 b = 하늘.getInstance();
하늘 c = 하늘.getInstance();
if(a==b && b==c) {
System.out.println("셋은 같은 싱글톤 객체입니다.");
}
}
}
>> 셋은 같은 싱글톤 객체입니다.
getInstance() 메소드는 단 하나의 객체만 리턴하기 때문에
위 코드에서 변수 a,b,c는 동일한 하나의 객체를 참조한다.
💙 final 필드
초기값이 저장되면, 프로그램 실행 도중에 수정할 수 없다.
final 필드의 초기값을 지정하는 방법은 두 가지가 있다.
1. 필드 선언 시에 초기값 지정
2. 생성자에서 초기값 지정
public class 파이널필드 {
//필드 선언 시 초기값 지정
final int a = 3;
final int b;
//생성자에서 초기값 지정
public 파이널필드 (int x) {
this.b = x;
}
//a와 b의 값은 이제 바꿀 수 없다!
}
final 필드 = 상수?
final 필드도 한 번 초기화되면 수정할 수 없는데... 상수 아닌가요? => ❌ 아닙니다!
상수는 객체마다 저장할 필요 없이 공용성을 띠고, 여러값으로 초기화될 수 없어!
그런데 final 필드는 객체마다 저장되며, 생성자를 통해 여러가지 값을 가질 수 있음.
공용성을 띠는 상수는 static이면서 final이어야 한다.
//static final 타입 상수 = 초기갑
static final double PI = 3.141592;
상수는 객체마다 존재하는 것이 아닌, 클래스에만 존재하고, 초기값을 변경할 수 없습니다.
*참고
점프 투 자바 - static 예제 참고
혼공자바 교재 - 싱글톤 패턴 참고
'기록 > EC.crew 정기 모임 정리' 카테고리의 다른 글
[DEC.crew] 20230815 정모 ; 미래 설계 발표 ✨ (0) | 2023.08.15 |
---|---|
230327 EC.crew 4기 3주차 정모 (★2579 계단 오르기) (0) | 2023.03.27 |
230320 EC.crew 4기 2주차 정모 (★백준 1004 어린왕자) (0) | 2023.03.20 |
221117 EC.crew : 스택과 큐 (0) | 2022.11.18 |
221110 EC.crew : 그리디 알고리즘 (0) | 2022.11.10 |