static 변수
static은 주로 멤버 변수와 메서드에 사용한다.
package static1;
public class Data1{
public String name;
public int count;
public Data1(String name) {
this.name = name;
count++;
}
}
생성된 객체의 수를 세어야 한다. 객체가 생성될 때마다 생성자를 통해 인스턴스의 멤버변수인 count 값을 증가시킨다.
public class DataCountMain1 {
public static void main(String[] args) {
Data1 data1 = new Data1("A");
System.out.println("A count =" +data1.count);
Data1 data2 = new Data1("B");
System.out.println("B count =" +data1.count);
Data1 data3 = new Data1("C");
System.out.println("C count =" +data1.count);
}
}
실행 결과
=> 카운트는 증가하지 않는다. 객체를 생성할 때마다 Data 인스턴스와 count 변수가 새로 만들어지기 때문이다.
인스턴스에 사용되는 멤버변수 count 는 인스턴스끼리 서로 공유되지 않는다. 이 문제를 해결하려면 변수를 서로 공유해야 한다.
외부 인스턴스에 카운트 저장
Counter.java
package static1;
public class Counter {
public int count;
}
Data2.java
package static1;
public class Data2 {
public String name;
public Data2(String name, Counter counter){
this.name = name;
counter.count++;
}
}
DataCountMain2.java
package static1;
public class DataCountMain2 {
public static void main(String[] args) {
Counter counter = new Counter();
Data2 data1 = new Data2("A", counter);
System.out.println("A count =" +counter.count);
Data2 data2 = new Data2("B", counter);
System.out.println("B count =" +counter.count);
Data2 data3 = new Data2("C", counter);
System.out.println("C count =" +counter.count);
}
}
실행 결과
이번엔 값이 정상적으로 증가했다. Counter 인스턴스를 공용으로 사용하기 때문에 객체를 생성할 때 마다 값을 증가되는 것이다.
그러나 여기에는 불편한 점들이 있다.
Data2가 몇 개 생성됐는지를 구하기 위해서 무관한 Counter 클래스를 만들어야 한다.
static 변수 사용
특정 클래스에서 공용으로 사용할 수 있는 변수를 만들면 편리할 것이다. static 키워드를 사용하면 공용으로 사용하는 변수를 만들 수 있다.
Data3.java
package static1;
public class Data3 {
public String name;
public static int count; //static
public Data3(String name) {
this.name = name;
count++;
}
}
멤버 변수에 static을 붙이게 되면 static 변수, 정적 변수 또는 클래스 변수라 한다.
DataCountMain3.java
public class DataCountMain3 {
public static void main(String[] args) {
Data3 data1 = new Data3("A");
System.out.println("A count =" +Data3.count);
Data3 data2 = new Data3("B");
System.out.println("B count =" +Data3.count);
Data3 data3 = new Data3("C");
System.out.println("C count =" +Data3.count);
}
}
=> 코드를 보면 count 정적 변수에 접근할 때 클래스 명에 .(dot)을 사용한다.
- static이 붙은 멤버 변수는 메서드 영역에서 관리한다.
- 인스턴스 영역에 생성되지 않는다. 대신에 메서드 영역에서 이 변수를 관리한다.
- Data3("A") 인스턴스를 생성하면 생성자가 호출된다. 생성자에는 count++ 코드가 있는데 여기서 count 변수는 정적 변수 이다. 정적변수는 메서드 영역에서 관리하기 때문에 메서드 영역에 있는 count 의 값이 증가하는 것이다.
- Data3("B")를 호출해도 마찬가지 이다.
static이 붙은 정적 변수에 접근하려면 클래스명.변수명 으로 접근하면된다.
멤버변수의 종류
인스턴스 변수 : static이 붙지 않은 멤버 변수.
- 인스턴스를 생성해야 사용할 수 있고, 인스턴스에 소속되어 있다.
- 인스턴스를 만들 때마다 새로 생성된다.
클래스 변수: static이 붙은 변수
- 클래스 변수, 정적 변수, static 변수 등으로 부른다 .
- 클래스에 바로 접근해서 사용할 수 있고, 클래스 자체에 소속되어 있다.
- 클래스 변수는 자바 프로그램을 시작할 때 1개가 만들어진다. 인스턴스와는 다르게 여러 곳에서 공유하는 목적으로 사용된다.
변수와 생명주기
지역 변수(매개변수 포함) : 지역 변수는 스택 영역에 있는 스택 프레임 안에 보관된다. 메서드가 종료되면 스택프레임이 제거되면서 지역변수도 함께 제거된다.
인스턴스 변수: 인스턴스에 있는 멤버 변수를 인스턴스 변수라 한다. 힙 영역을 사용한다. 힙 영역은 GC가 발생하기 전까지는 생존하기 때문에 지역 변수보다 생존주기가 길다.
클래스 변수 : 클래스 변수는 메서드 영역의 static 영역에 보관된다. 메서드 영역은 프로그램 전체에서 사용하는 공용 공간이다. 클래스 변수는 해당 클래스가 JVM에 로딩 되는 순간 생성된다. 그리고 JVM이 종료될 때 까지 생명주기가 이어진다
힙 영역에 생성되는 인스턴스 변수는 동적으로 생성되고, 제거되는 반면 static 변수는 프로그램 실행 시점에 생성되고, 프로그램 종료와 함께 제거되므로 정적 변수라 한다.
* 인프런 '김영한의 실전 자바 - 기본편'을 참고하여 작성하였습니다.
'프로그래밍언어 > Java' 카테고리의 다른 글
[Java 기본] final 변수와 상수 (0) | 2024.07.12 |
---|---|
[Java 기본] static 메서드 (0) | 2024.07.12 |
[Java 기본] 스택 영역과 힙 영역 (0) | 2024.07.10 |
[Java 기본] 스택 영역 (0) | 2024.07.10 |
[Java 기본] 스택과 큐 자료구조 (0) | 2024.07.10 |