Hayden's Archive
[자바/Java] static 키워드 본문
- 변수는 크게 필드, 지역변수, 스태틱 변수 3가지로 나뉜다. ( 관련 포스팅 : https://hayden-archive.tistory.com/60?category=775409 )
- 자바에서는 정적 변수/스태틱 변수 Static Variable, 클래스 변수 Class Variable, 전역 변수 Global Variable 다 같은 말.
- static 키워드는 보통 상속을 하고 나서 다룸. 앞쪽에서 배울 성질이 아님. 객체를 이해한 다음에 이해해야 함. 중요!
- Keypoint :
1. 필드(멤버 변수)와 스태틱 변수가 어떻게 다른지 분명히 알아야 함.
2. 내가 설계할 때 변수를 어떤 걸 필드로 하고 어떤 걸 스태틱으로 할지 구분이 되어야 함.
static 키워드
1. static한 멤버(필드/메소드)는 객체 생성 없이 사용할 수 있다.
new라는 걸 통해 객체 생성하지 않아도 바로 쓸 수 있다.
2. static한 멤버는 객체 생성 이전에 미리 메모리에 올라가 있다.
- 객체 생성 = 메모리에 올린다. 근데 객체 생성하지 않아도 된다? = 미리 메모리에 올라가 있다는 소리
- class file load 되는 시점에 올라간다.
- 컴파일하면 클래스 파일이 만들어지는데 클래스 파일이 만들어지자마자 static도 메모리에 함께 올라감.
cf) 자바는 컴파일 단계, 실행 단계 둘 다 한다.(C는 컴파일만 하면 됨, 비주얼 베이직은 실행만 하면 됨.)
Java static, Heap, Stack 실행순서 참고 : https://blog.naver.com/haha7037/221863798692
< static 예시 > |
Math.random() =====> new Math, m.random() 이렇게 안 쓰고 바로 갖다 썼음. 계산하는데 메모리에 올리고 그런 게 아니라 바로바로 쓸 수 있게 하려고 미리 메모리에 올려놓은 것. |
main() =====> public static void main() |
Integer.parseInt() =====> 문자열을 숫자로 변환시키는데 역시 객체 생성 없이 바로 갖다 씀. |
System.out.print() =====> System 클래스에 out이라는 필드가 있음. out이 static한 것. new System 이렇게 안 씀. -> 원래는 out을 쓰려면 메모리에 만들어야 함. 원래라면 System s = new System(); -> s.out 이렇게 씀 -> 그런데 필드가 static이라면 객체 생성할 필요가 없다. 미리 메모리에 올라가 있다. 그래서 바로 쓴다. System.out ( 관련 포스팅 : https://hayden-archive.tistory.com/79?category=775409 ) |
3. static한 멤버는 생성된 객체들이 모두 공유한다!!!!(☆☆☆)
4. static은 final과 함께 거의 사용된다.
5. 싱글톤 패턴시 필수적으로 사용
- 싱글톤 패턴(Singletone Pattern) -> 클래스로부터 객체는 원하는 만큼 만들 수 있는데, 객체를 찍어내는 게 클래스인데... 클래스로부터 객체를 하나만 만들 수 있도록 막아놓은 것. OOP에서 굉장히 중요한 패턴!
==> 클래스로부터 오직 단 한 개의 인스턴스만 생성하고 외부로부터 객체 생성을 하지 못하도록 막아두는 패턴.
- 싱글톤 패턴 코드 작성 방법
1. 클래스에서 일단 하나의 객체를 생성 --- private static 으로 지정해서 생성
2. 외부에서 객체생성을 못하도록 막는다 --- private 생성자() // 생성자 앞에 private를 붙이면 된다.
3. 하나 만들어놓은 객체를 외부에서 사용할 수 있도록 미리 메모리에 올려놓고 열어둔다 --- public static 으로 지정
class Factory{
private static Factory factory = new Factory(); //1
private Factory() { //2
System.out.println("Car Factory.... Creating.....");
}
public static Factory getInstance() { //3
return factory;
}
}
다른 클래스에서 가져다 쓸 때 Factory f = new Factory(); 못 만듦. 에러 남.
=====> 에러 나는 이유? 객체를 생성할 때마다 호출되는 게 생성자인데 생성자 호출을 private로 막아둠.
// 객체 생성 못하는데 접근해야 하는데.. 못 받아쓰는 상황...
// 그래서 반드시 public static을 써야 함.
// public static Factory getInstance()
// 그런데 public Factory getInstance()라고 써서 못 쓰는 실수를 엄청 많이 함.
public class StaticExamTest5 {
public static void main(String[] args) {
Factory factory1 = Factory.getInstance();
Factory factory2 = Factory.getInstance();
Factory factory3 = Factory.getInstance();
System.out.println(factory1);
System.out.println(factory2);
System.out.println(factory3);
// 주소값 찍어보면 다 같은 주소값 나옴. 다 똑같은 객체 factory가 리턴된 것.
}
}