Programming/Java

7. Static

주죵 2021. 1. 3. 21:06
728x90
반응형

Static의 이해

필요에 의해 class를 만들고, 생성자를 통해 객체로 만들어서 사용을 했다.

이러한 방식으로 모든걸 처리하면 다음과 같은 문제가 생긴다.

예시를 살펴보자.


아빠 지갑(class)에 200원이 있다. 아이들이 100원을 달라고 할때 100원의 아빠지갑 객체가 형성된다고 하자.

세명의 아이들이 100원을 받는다면 3개의 객체가 생긴다.

프로그래밍의 입장에선 클래스에선 무한한 객체 생성이 가능하고, 각 객체는 독립적이므로 실행이 가능한 경우가 된다.

하지만 현실세계에선 200원밖에 없는데 300원을 준것이므로 불가능한 경우이다.


이를 해결하는 방법은 아빠 지갑 객체가 세 아이들 모두에게 '공유'되면 된다

그렇다면 세번째로 돈을 받아간 아니는 100원을 받지 않고, 오류없이 동작한다.

이를 가능하게 하는 '공유'의 개념을 static이라고 생각하자.

클래스에서 객체를 생성한 후 객체를 공유하는것이 아니라, 객체가 생성되기 전에 클래스에 있는 데이터를 공유하는것이다.


예제코드를 통해 살펴보자.

//예제 코드1.
package Papa;

public class Papapouch {
	
	public static int MONEY = 200; //static을 통한 공유
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		

	}

}


Papapouch에는 200원의 돈이 들어있다.

package children;
import Papa.Papapouch;

public class Firstchild {
	public Firstchild() {
		
	}
	public void takeMoney(int money) {
	//객체생성없이 바로 class의 MONEY에 접근
	//static 선언시 객체생성없이 바로 접근이 가능하다
		Papapouch.MONEY = Papapouch.MONEY - money;
		if(Papapouch.MONEY < 0) System.out.println("첫째는 돈이 없어서 못바다잉 ㅠ");
	
	}

}

public class Secondchild {
	public void takeMoney(int money) {
		//객체생성없이 바로 class의 MONEY에 접근
		//static 선언시 객체생성없이 바로 접근이 가능하다
			Papapouch.MONEY = Papapouch.MONEY - money;
			if(Papapouch.MONEY < 0) System.out.println("둘째는 돈이 없어서 못바다잉 ㅠ");
		
		}

}

public class Thirdchild {

	public void takeMoney(int money) {
		//객체생성없이 바로 class의 MONEY에 접근
		//static 선언시 객체생성없이 바로 접근이 가능하다
			Papapouch.MONEY = Papapouch.MONEY - money;
			if(Papapouch.MONEY < 0) System.out.println("셋째는 돈이 없어서 못바다잉 ㅠ");
		
		}

}

 

세명의 아이들은 takeMoney 메소드를 통해 각각 돈을 받아간다.

눈여겨볼점은 static 변수는 객체생성없이 바로 접근 가능하다는것!

import Papa.Papapouch;
import children.*;
public class MainClass_papa {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Firstchild firstchild = new Firstchild();
		firstchild.takeMoney(100);
		Secondchild secondchild = new Secondchild();
		secondchild.takeMoney(100);
		Thirdchild thirdchild = new Thirdchild();
		thirdchild.takeMoney(100);
		
		System.out.println("papapouch money :"+Papapouch.MONEY);

	}

}

 

 

세명의 아이들의 객체를 각각 형성한후 100원씩 가져가면 아래와 같은 결과가 출력된다

 

셋째는 돈이 없어서 못바다잉 ㅠ
papapouch money :-100

 


Static은 class 변수

static 키워드를 사용한 변수는 '클래스 변수' 이다.

객체는 클래스에서 생성(복사)되어진다. 또한 앞서 배운것처럼 하나의 클래스에서 무한한 객체를 생성할 수 있고, 그 객체는 각각 독립적인 다른 덩어리이다.

하지만 static이 붙은 변수는 객체 변수가 아닌 클래스 변수로써, 객체가 생성되기 전에 존재한다.

 

메모리 관련해서 본다면

데이터영역에는 객체가 생성되기 이전 class들이 모여있는 영역이다.

이후 new연산자와 생성자를 통해 객체를 만들면 Heap영역으로 객체의 메모리가 저장된다.

자바의 가비지 콜렉터는 Heap영역만 관리한다. 즉, 메모리에 존재하는 객체의 메모리를 관리하는것이다.

 

 

Static의 장, 단점

- 장점

위와 같이 static 변수는 객체생성과 상관 없이 class와 함께 존재한다. 즉 객체 생성과 상관없이 메모리에 상주한다. 이렇게 생성을 하지 않고도 존재한다는 것은 그만큼 heap영역의 메모리는 사용하지 않아도 된다는 것. 따라서 객체생성에 따른 메모리 부족 현상을 막을 수 있다.

 

- 단점

하지만 항상 메모리에 상주하며 가비지컬렉터의 통제 밖에 있다. 따라서 프로젝트가 커지고 시스템 운영 시간이 늘어나면 운영속도에 악영향을 느낄 수 있다. 따라서 static은 신중하게 사용해야한다.

 

static변수로 사용되는 대표적인 예는 주로 '상수'이다.

원주율 = 3.1415926535.... 의 무한소수이다.

이러한 경우 원주율을 3.14의 static 변수로 정의해놓고 사용하기로 약속한다면 공유된 static변수를 사용가능하다.

여기서 나오는 의문 : 처음에 약속한 static값을 누가 변경해버리면 오류가 생기지 않나요?

A : final 을 사용한다. (더이상 변경 불가)

 

예시

public class PIClass{
	public static final double PI = 3.14;
    public PIClass(){
    }
}

 

출처 : 신입SW 인력을 위한 실전 자바(by 블스)

728x90

'Programming > Java' 카테고리의 다른 글

9. 추상클래스  (0) 2021.01.07
8. 상속  (0) 2021.01.04
6. 패키지 및 접근제한  (0) 2021.01.03
5. 객체지향 프로그래밍  (0) 2021.01.03
4. 객체지향 프로그래밍  (0) 2021.01.03