자바 제어자1 (modifier) - 2. Static

Ⅱ. Static

1. static(정적) 키워드 (필드)

 - 정적 멤버로 선언

    ※ 정적 멤버 : 선언되는 순간부터 프로그램 종료시까지 존재하는 멤버

 -  객체생성 없이 바로 사용 가능 (static 메모리 영역에 따로 저장됨)

 ※ 동적 할당(Dynamic Allocation) : c언어(자바)에서 힙 영역에 메모리를 할당받는 작업

    → 참조자료형 기반으로 객체 생성

// Example 인스턴스 필드와 정적필드의 활용 방법
package sample;

class A {
	int m = 3;		//인스턴스 필드 (논스태틱 멤버)
	static int n = 5;	//정적(static) 필드 (스태틱 멤버)
}

public class Main {
	public static void main(String[] args) {		
		// 1. 인스턴스 필드 활용방법 (항상 객체생성을 한 후 사용가능)
		A a1 = new A();
		System.out.println(a1.m);	// 3
		
		// 2. 정적(static) 필드 활용 방법
		// 방법#1 (객체생성없이 클래스 이름으로 바로 활용)
		System.out.println(A.n);	// 5
		// 방법#2 (객체생성 후 활용 : 인스턴스와 동일) : 가능한 지양
		A a2 = new A();
		System.out.println(a2.n);	// 5
	}
}

    ※ 스태틱 멤버와 인스턴스 멤버의 관계

        - 스태틱 멤버는 선언되고부터 존재하나, 인스턴스 멤버는 그렇지 않음

        - 스태틱 멤버는 인스턴스 멤버에 접근할 수 없음

 

 - static 필드의 객체간 공유기능

// Example
package sample;

class A {
	int m = 3;		//인스턴스 필드
	static int n = 5;	//정적(static) 필드
}

public class Main {
	public static void main(String[] args) {		
		A a1 = new A();
		A a2 = new A();
		
		// 인스턴스 필드
		a1.m = 5;
		a2.m = 6; 		
		System.out.println(a1.m);	// 5
		System.out.println(a2.m);	// 6
		
		// 정적필드
		a1.n=7;
		a2.n=8;				// a1과 a2의 static의 n 값이 8로 변경 
		System.out.println(a1.n);	// 8
		System.out.println(a2.n);	// 8
		
		A.n=9;				// 클래스 A의 n 값이 9로 변경
		System.out.println(a1.n);	// 9
		System.out.println(a2.n);	// 9
	}
}

 

2. static 키워드 (메소드) → 객체생성 없이 바로 사용 가능

//Example 인스턴스 메소드와 정적 메소드
package sample;

class A {
	void abc() {			// 인스턴스 메소드
		System.out.println("instance 메소드");
	}
	static void bcd() {		// 정적메소드
		System.out.println("static 메소드");
	}
}

public class Main {
	public static void main(String[] args) {		
		// 1. 인스턴스 메소드 활용방법 (객체생성 후에만 사용가능)
		A a1 = new A();
		a1.abc();		// instance 메소드
		
		// 2. 정적 메소드 활용방법 
		// 방법1. 클래스 이름으로 바로 접근하여 사용
		A.bcd();		// static 메소드
		// 방법2. 객체생성후에도 사용가능 : 가능한 지양
		A a2 = new A();
		a2.bcd();		// static 메소드		
	}
}

 

3. static  초기화 블록

 - instance 필드의 초기화 위치 → 생성자

 - static 필드의 초기화 위치 → static { } (생성자 호출없이 사용가능하기 위해)

//Example
package sample;

class A {
	int a;
	static int b;	
	static {
		b = 5; // static 필드의 초기화는 static {} 내에서 수행
		System.out.println("클래스 A가 로딩되었습니다!!");
	}	
	A() {
		a = 3; // 인스턴스 필드 초기화는 생성자에서 일반적으로 수행
		// b = 5;
	}
}

public class Main {
	public static void main(String[] args) {		
		System.out.println(A.b);	// 5		
	}
}

 

 - main() 함수에 static이 붙은 이유 : main 메소드를 바로 사용할 수 있게끔 하기 위해