개발 일기

Static 이란? 본문

카테고리 없음

Static 이란?

flow123 2022. 3. 7. 20:16

Static이란? 

Static 변수를(클래스 변수라고도 한다) 가지는 클래스를 아무리 많이 생성하더라도, static 변수는 하나만 만들어진다.

이는 모든 객체가 공유하는(바라보는) 변수가 된다. 

 

자바에서 static 키워드를 쓴다는 것의 장점이 뭘까?

Static 으로 선언 되었을 때는, 객체를 생성하지 않고도 사용할 수 있다. 

메모리에 한번 할당되고, 프로그램이 종료될 때 해제되는 것이다.

 

단점: GC 관리 영역은 Heap이고,  static 변수는 Data 영역에 저장된다. 즉 GC 관리가 되지 않는다. 그러다보니 Static을 자주 사용하면, 프로그램이 종료 까지 메모리가 할당된 채로 존재. 자주 사용하면 시스템 퍼포먼스에 악영향을 미친다.

 
참고로, Static 메서드에서 접근하는 변수 역시 static 이 선언되어야 한다.

메모리 할당과 연관 지어서 생각해보자., static은 객체의 생성과 상관없이 접근한다

non-static 변수/메서드의 경우, 메모리가 할당되지 않았을 것이다. 즉 할당된 영역에서 할당되지 않은 영역에 접근할 수는 없는 것이다. 

 

package Chapter08;

public class ReferenceStaticVariable {
	static String name;

	public ReferenceStaticVariable() {
	}

	public ReferenceStaticVariable(String name) {
		this.name = name;
	}

	public static void main(String args[]) {
		ReferenceStaticVariable reference = new ReferenceStaticVariable();
		reference.checkName();
	}

	public void checkName() {
		ReferenceStaticVariable reference1 = new ReferenceStaticVariable("Sangmin");
		System.out.println(reference1.name);
		ReferenceStaticVariable reference2 = new ReferenceStaticVariable("Lee");
		System.out.println(reference1.name);
	}
}

이유: reference1인데도 왜 Lee 가 나왔을까?(Sangmin이 아닌)?

이는 reference2를 참조했을 때 나왔어야 할 결과이다. 아래 캡처를 보면, reference1, 2를 쓴 결과가 같다. 

여기서 name 은 인스턴스 변수가 아닌, 클래스 변수이다. 

인스턴스 변수는 인스턴스가 생성될 때, 클래스 변수는 클래스가 로딩 될 때 생성된다. 

static 으로 선언하게 되면, static 변수를 가지는 클래스를 여러개 생성해도 (reference1, reference2) 

static 변수는 오직 하나만 만들어지고, 이는 모든 객체가 공유하는 변수가 된다. 그래서 "Lee"로 name을 넣은 뒤에는, reference1 의 name 도 Lee로 변경된 것이다. 

 

 

Static Block

용도: 객체는 여러개 생성하지만, 한 번만 호출되어야 하는 코드가 있다면? static 블록을 사용하자. 

public class StaticBlock {
	static int data = 1;

	public StaticBlock() {
		System.out.println("StaticBlock constructor");
	}

	static {
		System.out.println("*** First Static block. ***");
		data = 3;
	}

	static {
		System.out.println("*** Second static block. ***");
		data = 5;
	}

	public static int getData() {
		return data;
	}
}
public class StaticBlockCheck {
	public static void main(String args[]) {
		StaticBlockCheck check = new StaticBlockCheck();
		check.makeStaticBlockObject();
	}

	public void makeStaticBlockObject() {
		System.out.println("Creating Block1");
		StaticBlock block1 = new StaticBlock();
		System.out.println("Created Block1");
		System.out.println("--------------");
		System.out.println("Creating Block2");
		StaticBlock block2 = new StaticBlock();
		System.out.println("Created Block2");

	}
}

두 개의 staticBlock 객체를 만들었지만 static 블록은 1번만 호출된다.

생성자가 호출되기 전에 static 블록이 호출된다.

-> 클래스 초기화 할 때 꼭 수행되어야 하는 작업이 있을 경우 유용하다.   

 

데이터가 어떻게 변하고, 생성자가 호출하는지를 살펴보기 위해 아래 구문을 추가한다. 

 

	public void makeStaticBlockObjectWithData() {
		System.out.println("data=" + StaticBlock.getData());
		StaticBlock block1 = new StaticBlock();
		block1.data = 1;
		System.out.println("--------------");
		StaticBlock block2 = new StaticBlock();
		block2.data = 2;
		System.out.println("data=" + StaticBlock.getData());

	}

(1)Data 가 출력되기 전에, static 블록들이 호출되어 두 줄의 결과를 먼저 출력한다. 

static 블록은 생성자가 불리지 않더라도 클래스에 대한 참조가 발생하자 마자 호출되기 때문이다. 

 

 

출처: 자바의 신 8장

https://donggeuri0320.tistory.com/entry/%EC%9E%90%EB%B0%94java-static-%EC%98%88%EC%95%BD%EC%96%B4

 

자바(java) - static 예약어

static 예약어는 메서드나 멤버변수에 정의할 수 있으며 지역변수나 클래스에게는 정의 할 수 없다. (예외 - 내부클래스) # static 메서드, 멤버변수 정의 형식  [접근제한] static [반환형] 메서드명(

donggeuri0320.tistory.com

 

 https://mangkyu.tistory.com/47

Comments