[JAVA] Static 키워드

@욕심쟁이

·

2020. 9. 14. 18:44

반응형

 1. Static멤버변수 (정적(static)멤버 변수 = 클래스 멤버 변수)이란?

  - 클래스가 메모리(메서드 영역)에 로딩 될때 함께 로딩되는 멤버
  - 인스턴스 생성과 상관없음 인스턴스 생성 없이 클래스명만으로 접근 가능
   (클래스명.정적멤버변수명)
  - 정적멤버변수의 경우 모든 인스턴스에서 하나의 값을 공유함 
    → 공유메모리 공간을 사용하므로 모든 인스턴스가 주소값 공유
  - 로컬변수는 메서드 호출 시 생성 및 소멸과 관계있고,
    인스턴스변수는 인스턴스 생성 및 소멸과 관계있고,
    정적변수(클래스변수)는 클래스 로딩 (프로그램 시작) 및 클래스 제거(프로그램 종료)와 관계있음(static은 클래스생성소멸 (프로그램 시작종료))

참고) 프로그램 동작 순서

public class Ex2 {
	public static void main(String[] args) {
			
		//staticEx 클래스의 클래스(정적)변수 a는
		//클래스가 메모리에 로딩될떄함꼐 로딩되므로
		//인스턴스 생성전에 메모리에 로딩되며, 인스턴스 생성 없이도 
		//StaticEx클래스명만으로 접근가능한 멤버이다!
		System.out.println(StaticEx.a);//10
//		System.out.println(StaticEx.b);
		//=>인스턴스 멤버변수b는 반드시 인스턴스통해서만 접근가능 
		StaticEx se = new StaticEx();
		//=> 인스턴스 생성시 Heap영역에 인스턴스 멤버도 함께 로딩됨
		System.out.println(se.a);  // static방법으로 접근가능(클래스명.정적멤버변수)//10
		//정적 멤버변수도 일반 인스턴스 멤버변수처럼 접근 할 수 있으나 가급적 static접근 방식(클래스명.변수명)으로 접근하도록 하자
		System.out.println(se.b);//20
		
		//변수 a의 값을 100으로 변경, b의 값을 200으로 변경 후 출력
		StaticEx.a = 100;
		se.b = 200;
		System.out.println("변경후 StaticEx.a: "+ StaticEx.a); //100
		System.out.println("변경후 se.a: "+ se.a);//100
		System.out.println("변경후 se.b: "+ se.b);//200
		
		System.out.println("===============================");
		
		StaticEx se2 = new StaticEx();
		//인스턴스를 새로 생성하더라도 정적멤버변수는 
		//하나의 메모리공간을 모든 인스턴스에서 공유하므로 
		//하나의 인스턴스에서 값을 변경하면 모든 인스턴스가 변경된 값을 공유
		System.out.println("se2.a: "+ se2.a);//변경된 100이 출력됨
		se2.a=300;
		System.out.println("se2.a: "+ se2.a);//변경된 100이 출력됨		
		System.out.println("se2.b: "+ se2.b);//새인스턴스 값 20 출력됨

		System.out.println("===============================");
		
		StaticEx se3 = new StaticEx();
		System.out.println("se3.a: "+ se3.a);//변경된 300이 출력됨
		
		System.out.println("===============================");
		
		//대표적인 static멤버변수의 예
		//수학관련 기능을 제공하는 Math클래스의 멤버변수는 모두 static
		double pi = 3.1415926535;
		System.out.println("파이값 : "+pi);
		//Math클래스에 상수PI가 제공되며 static멤버변수로 제공됨(JAVA API)
		//=> 별도의 인스턴스 생성없이 클래스명만으로 접근가능
		System.out.println(Math.PI);
		//정수를 다루는 Integer클래스(Byte클래스)의 멤버변수는 모두 static
		System.out.println("INT형 표현봄위 최소 값 : "+ Integer.MAX_VALUE);
		System.out.println("INT형 표현봄위 최소 값 : "+ Integer.MIN_VALUE);
		System.out.println("Byte형 표현봄위 최소 값 : "+ Byte.MAX_VALUE);
		System.out.println("Byte형 표현봄위 최소 값 : "+ Byte.MIN_VALUE);
		
		
	} 
	
}
class StaticEx{
	static int a = 10; // 클래스(static = 정적)멤버변수 선어
	int b = 20;//인스턴스 멤버변수 선언
	
	
	
}

2. 정적(static)메서드

 - 메모리 로딩 시점은 정적 멤버변수와 동일함
 - 호출 방법도 정적 멤버변수와 동일함
 - 메서드 정의시 리턴타입 앞에 static키워드를 붙여서 정의

- (클래스명.정적메서드명())

public class Ex3 {
	public static void main(String[] args) {
		//인스턴스 생성 전 클래스명을 사용하여 멤버메서드 호출
		StaticEx2.staticMethod(); //정적메서드 staticMethod() //정적멤버메서드 호출 가능
//		StaticEx2.nomalMethod(); //인스턴스 멤버메서드는 호출불가능
		
		StaticEx2 se2 = new StaticEx2();
		se2.normalMethod(); //일반메서드 normalMehod()
		se2.staticMethod(); //정적메서드 staticMethod() // 인스턴스 통해 접근해서 메서드 호출도 가능하나 클래스명으로 접근하는것을 권장함
		
		System.out.println("===================================");
		//static멤버도 pivate접근제한자 사용 시 외부클래스에서 접근 불가
		//System.out.println("StaticEx3.a : " + StaticEx3.a);
		//따라서, Getter/Setter를 사용하여 static멤버에 접근해야함

		System.out.println("StaticEx3.getA() = "+ StaticEx3.getA());//static메서드로 정의 시 클래스명만으로 접근이 가능해진다!
		StaticEx3 ex3 = new StaticEx3();
		System.out.println("ex3.getA() = "+ ex3.getA());
		
				
	}
}

class StaticEx2{
	public void normalMethod() {
		System.out.println("일반메서드 normalMehod()");
	}
	public static void staticMethod() {
		System.out.println("정적메서드 staticMethod()");
	}
}
class StaticEx3{
	//static멤버변수와 static메서드 정의시 주의사항!
	private static int a =10;  // 클래스 로딩시 (인스턴스생성 전 )함께로딩
	private int b = 20; // 인스턴스 생성시 로딩
	//=======================================
	
	public static int getA() {
		return a;
	}
	
	public static void setA(int a) {
		//this.a = a;  // this에는 자신의 인스턴스 주소 (오류발생)
		//static메서드 내에서는 레퍼런스this사용불가 
		//static메서드 로딩시점에 인스턴스생성이 되지 않았기 때문에 this를 사용 할 수 없다.
		//(super.(부모클래스의 인스턴스 주소)도 사용 불가능)
		StaticEx3.a = a;
		//=> 레퍼런스 this대신에 클래스명을 통해 접근가능
		
	}
	public static void print() {
		System.out.println("a = "+ a);
		//System.out.println("b = "+ b); 
		//b는 인스턴스변수 /인스턴스가 생성되지 않았는데 static이 아닌 멤버변수(인스턴스멤버변수)사용불가
		//클래스 (static멤버)로딩 시점에서는 인스턴스 멤버는 생성되기 전이기 떄문(this와 동일원인)
	}
	
	//=======================================
	public int getB() {
		return b;
	}

	public void setB(int b) {
		this.b = b;
	}

}

 

반응형