static

9mond·2023년 7월 11일
0
post-thumbnail
post-custom-banner

1. static 키워드

  • 객체 간의 공유 자원을 표현하는 static 키워드
  • 클래스를 설계할 때, 멤버변수 중 모든 객체에서 공통적으로 사용해야 하는 값에 static을 붙인다.
  • static이 붙은 멤버변수는 객체의 개수에 상관없이 단 하나만 생성되며, 이를 모든 객체가 공유하기 때문에 메모리를 효율적으로 사용할 수 있다.
	public class Article{
		private static int count;		// 전체 글 수
		private static String category	// 카테고리
		private int num;				// 글 번호
		private String title;			// 제목
		private String regDate;			// 날짜

2. 컴퓨터의 메모리 구조

  • 코드 영역(고정 영역)
    -> 프로그램의 코드가 저장되는 영역
    -> 이 영역의 저장된 명령어들은 CPU가 하나씩 가져가 실행한다.
  • 데이터 영역(고정 영역)
    -> 전역변수static으로 선언되는 변수가 할당된다.
    -> 이 영역에 할당되는 변수들은 프로그램 시작과 동시에 메모리 공간이 할당되어 종료될 때까지 남아있게 된다.
  • 힙 영역(동적 영역)
    -> 프로그래머가 원하는 시점에 변수를 할당하고 소멸시키는 영역
    -> 메모리의 동적 할당 시에 사용된다. 객체가 생성되는 영역
  • 스택 영역(동적 영역)
    -> 함수가 실행될 때 사용되는 파라미터지역변수에 대한 메모리 공간
    -> 함수의 종료와 함께 소멸된다.

3. 하나의 프로그램이 사용되는 메모리 영역

  • 고정영역
    -> 프로그램이 실행되면 실행파일이 메모리에 로드되면서, 실행파일의 용량만큼 RAM을 사용한다.
    -> 실행파일의 크기는 변할 수 없으므로 이 영역의 크기는 고정 크기를 갖는다.
  • 동적영역
    -> 프로그래머가 new 키워드를 사용해서 객체나 배열을 생성하며 사용된다
    -> 또 다른 경우는 메서드가 호출되는 동안 사용될 파라미터지역변수가 생성된다.
    -> 메서드가 종료되거나 객체가 더이상 사용되지 않으면 생성된 변수나 객체는 메모리에서 사라지므로, 이 영역은 유동적인 크기를 갖게 된다.

4. static 데이터의 생성위치

  • static 데이터는 메모리의 고정영역 중 데이터 영역에 생성되고, 일반 멤버변수객체는 동적영역 중 Heap메모리 영역에 생성된다.

5. 프로그램이 메모리를 사용하는 순서

  • 최초 실행 시 고정 영역에 실행파일 만큼의 메모리를 점유한다.
  • 프로그램이 각종 동작을 수행하는 동안 동적영역을 사용한다.

6. 멤버변수와 static 멤버변수의 차이

  • static 변수는 프로그램의 실행과 동시에 객체의 생성 여부와 상관없이 이미 존재하기 때문에 소스코드에서는 특정 클래스 안에 명시하지만, 그 클래스를 통해서 생성되는 객체나 그 안에 포함되는 멤버변수와는 다른 존재이다.
  • 객체가 생성되지 않았더라도 이미 존재하고 있기 때문에 static 변수는 객체의 이름을 통해 접근하는 것이 아니라, 클래스의 이름을 통해서 접근해야 한다.
  • 단, static 변수가 선언된 클래스 안에서는 변수 이름으로 직접 접근이 허용된다.
	// Article 클래스 및 다른 클래스에서 접근하는 경우
	Article.count = 3;
	Article.category = "공지상항";

	// Article 클래스에서 접근하는 경우
	count = 3;
	category = "공지사항";

7. static 데이터에 접근하기 위한 메서드

  • 클래스에서 정의하는 일반 메서드들은 객체의 생성과 동시에 동적 메모리 영역에서 활성화 된다.
    -> 동적 메모리 영역의 입장에서는 고정 메모리 영역의 자원들은 항상 존재한다.
    -> 고정 메모리 영역의 자원들은 동적 메모리의 자원들이 항상 존재하는 것이라는 보장을 받지 못한다.

  • 그러므로 객체의 생성과 상관없이 static 변수에 접근하기 위한 메서드를 만들 필요가 있는데, 메서드의 정의 과정에서 static 키워드를 사용하면 static 자원에 접근하기 위한 메서드를 만들 수 있다.

8. static 메서드 사용 시의 제약 사항

  • 메모리 영역의 차이 때문에 static 메서드는 동적 메모리 영역의 멤버변수를 사용하거나, static이 아닌 일반 멤버함수를 호출할 수 없다.

  • 고정 영역
    -> static 변수static 멤버함수가 생성된다.
    -> 이 영역의 자원들은 프로그램이 실행되는 동안 항상 존재한다.
    -> 동적 메모리 영역의 자원들은 항상 존재하는 것이 아니기 때문에 static 멤버 함수는 동적 메모리 영역의 멤버변수를 사용하거나, static이 아닌 일반 멤버함수를 호출할 수 없다.

  • 동적 영역
    -> 객체, 객체 안에 멤버변수, 메서드, 메서드가 호출되었을 때 사용되는 지역변수 등이 생성된다.
    -> 이 영역의 자원들은 생성과 제거가 유동적으로 반복된다.
    -> static 자원은 항상 존재하는 것이므로 동적 영역에서는 static 변수를 활용하거나, static 멤버함수를 호출할 수 있다.

예시

public class Article {
	
	 // static은 모든 객체가 공유하는 값이다. 
     // static값은 클래스 이름을 통해서 접근해야 하며, 객체의 생성 여부에 상관없이 사용이 가능하다.
	 // 전체 게시물의 수를 표현하기 위한 데이터
	private static int count = 0;
	
	// 모든 게시물은 하나의 카테고리 안에 존재한다고 가정한다.
	// 게시물의 분류를 구별하기 위한 데이터
	private static String category;
	
	private int num;		// 글 번호
	private String title;	// 글 제목
	private String regDate;	// 작성일시
	
	public Article(int num, String title, String regDate) {
		super();
		this.num = num;
		this.title = title;
		this.regDate = regDate;
		
		// 이 클래스에 대한 객체 생성 -> 게시물의 신규 등록
		// 게시물이 새로 등록될 때 마다, 전체 글 수를 의미하는 count 변수가 1씩 증가한다.
		// 전체 게시물 수는 모든 객체가 공유하는 값이므로, static으로 생성되어야 한다.
		count++;
	}
	public static int getCount() {
		return count;
	}
	public static void setCount(int count) {
		Article.count = count;
	}
	public static String getCategory() {
		return category;
	}
	public static void setCategory(String string) {
		Article.category = string;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getRegDate() {
		return regDate;
	}
	public void setRegDate(String regDate) {
		this.regDate = regDate;
	}
	@Override
	public String toString() {
		return "글 분류 = " + category
				+ ", 전체 글 수 = " + count
				+ ", Article [num=" + num
				+ ", title=" + title
				+ ", regDate=" + regDate + "]";
	}
}
public class Main01 {
	public static void main(String[] args) {
		Article.setCategory("자유게시판");
		Article a1 = new Article(1, "첫 번째 글", "2023-0711");
		Article a2 = new Article(2, "두 번째 글", "2023-0712");
		Article a3 = new Article(3, "세 번째 글", "2023-0712");
		
		System.out.println(a1.toString());
		System.out.println(a2.toString());
		System.out.println(a3.toString());
		
		// static 변수의 값을 변경하면 모든 객체가 영향을 받는다.
		Article.setCategory("공지사항");
		
		System.out.println(a1.toString());
		System.out.println(a2.toString());
		System.out.println(a3.toString());
	}
}
profile
개발자
post-custom-banner

0개의 댓글