SHUSTORY

06-3 static 변수 본문

프로그래밍/JAVA

06-3 static 변수

어서오시우 2023. 2. 23. 02:23
728x90

변수를 여러 클래스에서 공통으로 사용하려면?

예를 들어 생각해보자.

학생 클래스가 있고, 이를 이용하여 여러 학생 인스턴스를 만들 수 있다.

각 학생은 고유한 학번을 가지는데, 이 학번을 학생이 입학할 때 자동으로 생성되도록 만들고 싶다.

이 경우에는 각 인스턴스마다 따로 생성되는 변수가 아닌, 클래스 전반에서 공통으로 사용 가능한 변수가 필요하다.

그리고 학생이 한 명 생성될 때마다 기준 변수 값을 1씩 증가시켜 학생 인스턴스의 학번 변수에 대입하면 된다.

이 때 클래스에서 공통으로 사용하는 변수를 'static 변수'로 선언한다.

 

 

static 변수의 정의와 사용 방법

static 변수( 정적 변수, 클래스 변수 )는 자바뿐만 아니라 다른 언어에서도 비슷한 개념으로 사용되는 변수이다.

자바에서는 다른 멤버 변수처럼 클래스 내부에 선언한다.

변수를 선언할 때 다음과 같이 자료형 앞에 static 예약어를 사용한다.

static 문법

static 변수는 클래스 내부에 선언하지만, 타 일반 멤버 변수처럼 인스턴스가 생성될 때마다 새로 생성되는 변수가 아니다.

static 변수는 프로그램이 실행되어 메모리에 올라갔을 때 딱 한 번 메모리 공간이 할당되며,

그 값은 모든 인스턴스가 공유한다.

즉 static으로 선언한 변수는 인스턴스 생성과 상관 없이 먼저 생성되고 그 값을 모든 인스턴스가 공유한다.

 

학번 부여 예제

예제01

 

예제01은 serialNum이라는 static 변수를 선언했다.

해당 변수는 기준 값이 되며, ( 예제02 코드를 통해 )학생이 생성될 때마다 순서대로 증가하도록 할 것이다.

예제02

 

studentLee를 먼저 생성하고 이 참조 변수를 사용하여 전체 인스턴스에 공통으로 사용하는 serialNum 변수 값을 1 증가시킨다.

studentSon을 생성한 후 생성된 studentSon으로는 아무 연산도 수행하지 않는다.

이후 studentSon과 studentLee로 serialNum 변수 값을 출력하면 둘 다 1001로 증가된 serialNum 값이 출력된다.

이는 static으로 선언한 serialNum 변수를 모든 인스턴스가 공유하기 때문이다.

즉 두 개의 참조 변수가 동일한 변수의 메모리를 가리키고 있는 것이다.

 

그렇다면 학번을 자동으로 부여하는 예제를 만들어보자.

예제03

 

static 변수를 하나 선언한 후, 학생이 생성될 때마다 해당 변수 값이 1 증가하도록 한다.

여기서 주의할 점은 static 변수를 바로 학번으로 사용하면 안된다는 것이다.

static 변수는 모든 인스턴스가 공유하는 변수이므로 이를 학번으로 사용한다면 모든 학생들은 같은 학번을 가지게 된다.

학생의 멤버 변수로 선언한 뒤 학생이 생성될 때마다 증가한 serialNum 값을 해당 멤버 변수 studentID에 대입하도록 한다.

 

예제04

 

학생 인스턴스를 생성할 때마다 serialNum 변수 값은 증가하고, 생성되는 학생마다 1씩 증가된 학번이 부여된다.

static 변수는 같은 클래스에서 생성된 인스턴스들이 같은 값을 공유할 수 있으므로, 인스턴스 간에 공통으로 사용할 값이 필요한 경우 유용하게 사용 가능하다.

 

 

클래스 변수

static 변수는 인스턴스를 생성할 때마다 만들어지는 것이 아니고

클래스를 선언할 때 특정 메모리에 저장되어 모든 인스턴스가 공유하는 변수이다.

인스턴스보다 먼저 생성되어 인스턴스가 아닌 클래스 이름으로도 참조하여 사용할 수 있다.

예제04를 다음과 같이 변경하여 그 예시를 살펴보자.

예제05

 

static 변수는 인스턴스가 생성되지 않아도 사용할 수 있기 때문에 보통은 위와 같이 클래스 이름과 함께 사용한다.

* 참고로 이클립스에서 static 변수와 static 메서드는 이탤릭체로 나타난다.

 

 

클래스 메서드

일반 멤버 변수를 위한 메서드가 존재하듯 static 변수를 위한 메서드도 존재한다.

이를 static 메서드 또는 클래스 메서드라고 한다.

위 예제들에서 사용된 serialNum 변수를 사용하는 메서드를 만들어보자.

외부 클래스에서 serialNum 변수를 직접 참조하지 못하도록 priavate로 선언하고 get( ), set( ) 메서드를 생성한다.

* private로 선언하면 기존 예제02, 예제04, 예제05에서는 직접 참조할 수 없어 오류가 발생하기에 클래스를 따로 생성하겠다.

예제06

 

외부 클래스에서 serialNum을 사용하려면 get( ) 메서드를 호출하고, serialNum 값을 변경하려면 set( ) 메서드를 사용해야 한다.

다음은 실행 예제이다.

예제07

 

 

클래스 메서드와 인스턴스 변수

static 메서드( 클래스 메서드 ) 내부에서는 인스턴스 변수를 사용할 수 없다.

오류 발생

 

getSerialNum( ) 메서드는 static 예약어를 붙인 static 메서드( 클래스 메서드 )이다.

이 메서드는 세 종류의 변수를 사용하고 있다.

 먼저 int i를 살펴보자면, 이 변수는 메서드 내부에서 사용한 지역 변수이다.

     지역 변수는 메서드가 호출될 때 메모리에 생성되어 메서드가 끝나면 사라지는 변수이다.

     따라서 getSerialNum( ) 메서드 내부에서만 사용 가능하다.

return serialNum;의 serialNum 변수는 static 변수이다.

     따라서 static 메서드인 getSerialNum( ) 메서드 내부에서만 사용 가능하다.

studentName 변수는 오류가 발생한다.

     그 이유는 해당 변수는 Student2 클래스의 멤버 변수로, 인스턴스가 생성될 때 만들어지는

     인스턴스 변수이기 때문이다. staitc 메서드와 static 변수는 인스턴스가 생성되지 않아도 사용할 수 있어야 하므로

     오류가 발생하는 것이다.

     studentName처럼 인스턴스가 생성되어야 메모리가 할당되는 인스턴스 변수는 static 메서드에서 사용할 수 없다.

 

즉 클래스 메서드( static 메서드 ) 내부에서 지역 변수와 static 변수는 사용 가능하지만, 인스턴스 변수는 사용 불가하다.

또한 static 메서드 내부에서 인스턴스 변수를 사용할 수 없지만 반대로 일반 메서드에서 인스턴스 변수 사용은 가능하다.

일반 메서드는 인스턴스가 생성될 때 호출되는 메서드이며, static 변수는 이미 만들어진 변수이기에 일반 메서드에서도 static 변수를 호출할 수 있기 때문이다.

'프로그래밍 > JAVA' 카테고리의 다른 글

07-1 배열  (0) 2023.02.24
06-4 변수 유효 범위  (0) 2023.02.23
06-2 객체 간 협력  (1) 2023.02.23
06-1 this 예약어  (1) 2023.02.22
05-7 정보 은닉  (0) 2023.02.20