static 키워드는 주로 멤버 변수와 메서드에 사용된다.
-> 특정 클래스를 통해 생성된 객체의 수를 세는 프로그램으로 알아보자.
아래 코드는 의도대로 동작하지 않는다.
객체를 생성할 때마다 Data1의 인스턴스는 새로 만들어진다. 인스턴스에 포함된 count 변수도 새로 만들어지기 때문이다.
인스턴스에 사용되는 멤버변수 count 값은 인스턴스끼리 공유되지 않는다.
public class Data1 {
public String name;
public int count;
public Data1(String name) {
this.name = name;
count++;
}
}
main
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=" + data2.count);
Data1 data3 = new Data1("C");
System.out.println("C count=" + data3.count);
}
동일한 Counter 인스턴스의 count값을 증가시키면 값이 누적된다.
그런데 여기엔 불편한 점들이 있다.
1) Data2 클래스 관련 일인데, Counter 별도 클래스를 추가로 사용해야 한다.
2) Data2 생성자의 매개변수도 추가되고, 생성자가 복잡해진다. 호출 부분도 복잡해진다.
public class Counter {
public int count;
}
public class Data2 {
public String name;
public Data2(String name, Counter counter) {
this.name = name;
counter.count++;
}
}
main
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);
}
1) count를 static변수로 선언하였다. 이렇게 클래스 멤버변수에 static 키워드를 붙이게 되면 static 변수, 정적 변수 또는 클래스 변수라 한다. 객체가 생성되면 정적변수 count의 값을 하나 증가시켜 의도한 바대로 코드작성이 가능하다!
public class Data3 {
public String name;
public static int count; //static
public Data3(String name) {
this.name = name;
count++;
}
}
main
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);
//추가
//인스턴스를 통한 접근
Data3 data4 = new Data3("D");
System.out.println(data4.count);
//클래스를 통한 접근
System.out.println(Data3.count);
}
2) 정적 변수에 접근하는 방법: main()을 보면 Data3.count와 같이 클래스에 직접 접근하는 것같이 보인다. 클래스명.변수명 으로 접근하면 된다.
3) static이 붙은 멤버 변수는 메서드 영역에서 관리한다.
-> static이 붙은 멤버 변수 count는 인스턴스 영역에 생성되지 않는다.
4) Data3("A") 인스턴스를 생성하면 생성자가 호출된다.
5) 생성자에는 count++ 코드가 있다. count는 static이 붙은 정적 변수다. 인스턴스 영역이 아닌 메서드 영역에서 관리한다. 따라서 이경우 메서드 영역에 있는 count의 값이 하나 증가된다.(붕어빵 틀 자체를 바꾸는것과 같다)
6) 참고로, count++의 경우 Data3.count++과 같이 정적 변수에 접근 규칙으로 표기하는 것이 맞으나 자기자신(Data3) 클래스 내에서는 생략 가능하다.
