Static은 왜 사용하는가?
생성 시점 : Static의 생성 시점은 프로그램이 로드되는 순간 static 영역(데이터 영역) 으로 메모리가 올라간다.
따라서 불변하는 클래스, 메서드, 변수는 static으로 사용하는 것이 효율적인다.
단, static이 너무 큰 메모리를 차지한다면 로드될 시에 성능 측면에서 큰 부하가 생기므로 작은 메모리 만을 할당해서 적절히 사용하는 것이 효율적이다.
예시
아래 코드는 serialNum이 static으로 선언되어 있으며 10000으로 초기화되어있다.
Student 인스턴스를 생성할 때마다 serialNum은 1씩 증감한다.
package me.choi.chapter02.pizza.generic.staticex;
public class Student {
public static int serialNum = 10000;
private int studentID;
public String studentName;
public String address;
public Student(String studentName) {
this.studentName = studentName;
serialNum++;
studentID = serialNum;
}
public Student(int studentID, String studentName) {
this.studentID = studentID;
this.studentName = studentName;
serialNum++;
studentID = serialNum;
}
public int getStudentID() {
return studentID;
}
@Override
public String toString() {
return "Student{" +
"studentName='" + studentName + '\'' +
", address='" + address + '\'' +
'}';
}
}
studentChoi, studentLee라는 인스턴스를 생성하여 serialNum을 체크하면 1씩 증감되는 결과를 예상할 수 있다.
package me.choi.chapter02.pizza.generic.staticex;
public class StudentIDTest {
public static void main(String[] args) {
Student studentChoi = new Student("choi");
System.out.println(Student.serialNum);
Student studentLee = new Student("lee");
System.out.println(Student.serialNum);
System.out.println("학번 check");
System.out.println(studentChoi.getStudentID());
System.out.println(studentLee.getStudentID());
}
}
이때 serialNum은 studentChoi, studentLee각각의 힙 메모리에 올라가는 것이 아니라 로드 시 생성되었던 스태틱 영역을 참조한다.
따라서 studentChoi,studentLee은 같은 serialNum을 참조하게 된다.
위에 언급하였듯이 serialNum은 스태틱 영역에 올라감으로써 각각의 인스턴스가 생성되는 힙 메모리 영역에 생성되지 않았음을 보여준다.
static 변수를 사용하려면 위와 같이 클래스에서 직접 선언을 해야 한다.
static은 static으로 사용해야 한다.
public static int getSerialNum() {
int i = 0;
studentName = "Jun";
return serialNum;
}
위의 코드에서 틀린 점은 무엇일까?
1. int i는 static 메서드 내부에서 사용하는 지역변수 이기 때문에 문제없음.
2. serialNum 도 똑같은 static 변수 이기 때문에 상관없음.
단, studentName은 인스턴스 변수이기 때문에 사용할 수 없다.
studentName은 static 영역에 메모리가 올라간 이후의 작업이기 때문에 사용할 수 없다.
즉, new () 해서 인스턴스를 생성하고 나서 값을 생성할 수 있기 때문에 순서상 문제가 있다.
하지만 일반 메서드에서는 static 변수를 가공하여 사용할 수 있다. (프로그램이 로드될 때 이미 static은 메모리에 올라가 있기 때문에)
'Java > Java' 카테고리의 다른 글
(JAVA) 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2019.12.08 |
---|---|
(JAVA) 제네릭의 사용 (0) | 2019.12.08 |
(JAVA) 내부클래스의 종류 및 사용법 (1) | 2019.12.07 |
(JAVA) 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2019.12.04 |
(JAVA) 디폴트 생성자(default constructor) (0) | 2019.11.24 |