목차
<static 변수>
각 인스턴스 마다 따로 생성되는 변수가 아닌,
클래스 전반에서 공통으로 사용할 수 있는 '기준 변수'가 필요할 때가 있다.
예를 들어, 학생이 한 명 생성될 때마다 학번(기준 변수 값)을 하나씩 증가시켜 각 학생 인스턴스의 학번 변수에 대입해 주면 된다.
이때 클래스에서 공통으로 사용하는 변수를 'static 변수'로 선언한다.
<static 변수의 정의와 사용 방법>
1. 정의
static 변수란 다른 용어로 '정적 변수'라고도 한다.
static int serialNum;
(static 예약어) (자료형) (변수 이름)
static변수는 클래스 내부에 선언하지만, 다른 멤버 변수처럼 인스턴스가 생성될 때마다 생성되는 변수가 아니다.
static변수는 프로그램이 실행되어 메모리에 올라갔을 때 딱 한 번 메모리 공간이 할당된다.
그리고 그 값은 모든 인스턴스가 공유한다.
static 변수 사용법
package staticex;
public class Student1 {
public static int serialNum = 1000;
// static변수는 인스턴스 생성과 상관 없이 먼저 생성됨.
public int studentID;
public String studentName;
public int grade;
public String address;
public Student1() { //생성자
serialNum++;
studentID = serialNum;
//학생이 생성될 때 마다 serialNum 증가
//증가된 값을 학번 인스턴스 변수에 부여
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String name) {
studentName = name;
}
}
static변수(serialNum)하나를 선언.
생성자에 serialNum++;를 추가해 학생이 생성될 때마다 학번이 증가하고,
studentID = serialNum;으로 studentID변수에 증가 된 학번이 대입되도록 한다.
package staticex;
public class StudentTest2 {
public static void main(String[] args) {
Student1 studentLee = new Student1() ;
studentLee.setStudentName("이건희");
System.out.println(Student1.serialNum); //static변수이므로 클래스에서 참조가능
System.out.println(studentLee.studentName+"의 학번 : "+Student1.serialNum);
Student1 studentSon = new Student1();
studentSon.setStudentName("손민수");
System.out.println(Student1.serialNum); //static변수이므로 클래스에서 참조가능
System.out.println(studentSon.studentName+"의 학번 : "+Student1.serialNum);
}
}
학생 인스턴스를 생성할 때마다 serialNum변수 값은 증가한다. 그리고 두 학생의 학번은 다르게 설정된다.
이처럼 static변수는 같은 클래스에서 생성된 인스턴스들이 같은 값을 공유할 수 있으므로, 인스턴스 간에 공통으로 사용할 값이 필요한 경우 유용하게 사용 가능하다.
<클래스 매서드>
일반 멤버 변수를 위한 메서드가 존재하듯, static변수를 위한 메서드도 있다.
static메서드, 또는 클래스 메서드(class mathod)라고 한다.
package staticex;
public class Student2 {
private static int serialNum = 1000;
//private변수로 변경
public int studentID;
public String studentName;
public int grade;
public String address;
public Student2() {
serialNum++;
studentID = serialNum;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String name) {
studentName = name;
}
public static int getSerialNum() {
int i = 10;
return serialNum;
//serialNum의 get()메서드 (클래스 메서드)
}
public static void setSerialNum() {
Student2.serialNum = serialNum;
//serialNum의 set()메서드 (클래스 메서드)
}
}
package staticex;
public class StudentTest2 {
public static void main(String[] args) {
Student2 studentLee = new Student2() ;
studentLee.setStudentName("이건희");
System.out.println(Student2.getSerialNum()); //serial값을 가져오기 위해 get()메서드를 클래스 이름으로 직접호출
System.out.println(studentLee.studentName+"의 학번 : "+Student2.getSerialNum());
Student2 studentSon = new Student2();
studentSon.setStudentName("손민수");
System.out.println(Student2.getSerialNum());//serial값을 가져오기 위해 get()메서드를 클래스 이름으로 직접호출
System.out.println(studentSon.studentName+"의 학번 : "+Student2.getSerialNum());
}
}
StudentTest2.java의 7행과 12행 코드는 serialNum을 직접 참조하지 않고, get()메서드를 호출하여 참조합니다.
static메서드 또한 static변수처럼 인스턴스 참조 변수가 아닌 클래스 이름으로 직접 호출이 가능하다.
클래스 메서드와 인스턴스 변수
클래스 메서드 내부에서는 인스턴스 변수를 사용할 수 없다.
public class Student2 {
private static int serialNum = 1000; //private 변수
int studentID;
String studentName;
int grade;
String address;
...
pubilc static int getSerialNum() { //get()메서드(클래스 메서드)
int i = 10;
studentName = "이건희"; // 오류발생
return serialName;
}
...
getSerialNum()메서드는 static예약어를 붙인 클래스 메서드다.
이 메서드는 세 종류의 변수를 사용 중이다.
가장 먼저 선언한 int i 변수는 메서드 내부에서 선언했다. 이렇게 메서드 내부에서 선언한 변수를 그 지역에서만 사용한다고 해서 '지역 변수'라고 한다.
'지역 변수'는 메서드가 호출될 때 메모리에 생성되어 메서드가 끝나면 사라지는 변수이다.
마지막 return serialNum; 문장을 보면 serialNum변수는 static변수다. 그러므로 클래스 메서드인 getSerialNum() 메서드 내부에서도 사용이 가능하다.
두 번째 줄의 studentName변수는 오류가 발생한다.
이 변수는 Student2클래스의 멤버 변수로, 인스턴스가 생성될 때 만들어지는 인스턴스 변수이기 때문에 오류가 발생하는 것이다.
<static 변수와 static 메서드 연습하기>
학생마다 각각 다른 '학생 카드'가 발급됩니다. 학생 카드 번호는 학번에 100을 더한 값입니다.
Student3 클래스를 만들어 학생 카드 번호 멤버 변수를 추가하고, 학생이 생성될 때마다 학생 카드 번호를 부여합니다.
StudentTest6 클래스를 만들어 학생 두 명을 생성합니다. 두 학생의 카드 번호를 출력해 보세요.
package staticex;
public class Student3 {
private static int serialNum = 1000;
public int studentNum;
public int cardNum;
public String studentName;
public Student3() { // 생성자
serialNum++;
studentNum = serialNum;
cardNum = studentNum + 100; //카드번호는 학번 + 100
}
public int getSerialNum() {
return serialNum;
}
public void setSerialNum(int serialNum) {
Student3.serialNum = serialNum;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
}
package staticex;
public class StudentTest6 {
public static void main(String[] args) {
Student3 studentLee = new Student3();
studentLee.studentName = "이건희";
System.out.println(studentLee.studentName+"의 카드 번호는 "+studentLee.cardNum+"입니다.");
System.out.println(studentLee.studentNum);
Student3 studentPark = new Student3();
studentPark.studentName = "박윤섭";
System.out.println(studentPark.studentName+"의 카드 번호는 "+studentPark.cardNum+"입니다.");
System.out.println(studentPark.studentNum);
}
}
출력 값 :
[Do it! 자바 프로그래밍 입문] 도서로 공부하며 정리한 글입니다.