Hayden's Archive

[자바/Java] static 키워드 본문

Study/Java & Kotlin

[자바/Java] static 키워드

_hayden 2020. 4. 18. 22:14

- 변수는 크게 필드지역변수스태틱 변수 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가 리턴된 것.
	}
}