모든 객체가 공유하는 변수
클래스이름.static변수
👉 매우 번거롭다
👉 상수 형태로 저장하여, 메모리에서 데이터를 계속 사용할 수 있도록 함
힙(동적) 메모리
필요할때 로케이션 받아서 쓰고, 다쓰면 릴리즈 시킴
스택 메모리
함수나 메소드 안에서 쓰는 메모리
데이터 영역
처음 메모리 로드될때부터 공유되서 쓰다가, 프로그램 업로드 되면 사라지는 메모리
생성자 = 컨스트럭터(constructor)
객체가 초기화할때 작업은? 생성자에서 함!
👉 static 변수는 인스턴스에서 공통으로 사용하는 영역
= 클래스 변수 = 정적 변수 (VS 인스턴스 변수)
멤버 변수에만 사용이 가능
인스턴스가 생성될 때 만들어지는 변수가 아닌,
처음 프로그램이 메모리에 로딩될 때 메모리를 할당하는 변수
인스턴스 생성과 상관 없이 사용 가능 ⇒ 클래스 이름으로 직접 참조
static 변수값 변경 시 주의하기
❗ 값이 변경되는 순간, 클래스로부터 생성된 모든 객체에 영향 ❗
static int serialNum;
Student.serialNum = 100;
객체를 생성하지 않고 클래스 이름으로 직접 호출하여 접근
자주 사용하는 메소드
객체 생성 및 참조 변수로 접근 가능한 일반 멤버변수 → static
메소드에서 사용 불가
즉, 멤버변수와 static
메소드가 같은 클래스에 존재 → 다른 상성을 가진 존재
static 메서드(클래스 메서드)에서는 인스턴스 변수를 사용 불가
static
메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출 가능
👉 인스턴스 생성 전에 호출 될 수 있으므로, static
메서드 내부에서는 인스턴스 변수를 사용 불가
👉 생성이 안된 인스턴스 변수를 참조하면 안되기 때문
일반 메소드에서 static
변수 사용가능
👉 변수가 로드될 때 이미 메모리가 있기 때문
static
메소드에서 지역 변수 사용불가
👉 메소드가 불려질 시점에 메모리에는 해당 변수가 없을 수 도 있기 때문
변수의 유효 범위(scope)와 생성과 소멸(life cycle)
→ 각 변수의 종류마다 다름
지역변수, 멤버 변수, 클래스 변수
→ 유효범위와 life cycle, 사용하는 메모리도 다름
변수 유형 | 선언 위치 | 사용 범위 | 메모리 | 생성과 소멸 |
---|---|---|---|---|
지역변수 = 로컬변수 | 함수 내부에 | 함수 내부에서만 사용 | 스택 | - 함수 호출될 때 생성- 함수 끝나면 소멸 |
멤버변수 = 인스턴스 변수 | 클래스 멤버 변수로 | 클래수 내부에서 사용 - private 이 아니면, 참조 변수로 다른 클래스에서 사용 | 힙 | - 인스턴스 새성될 때 힙에 생성 - 가비지 컬렉터가 메모리 수거할 때 소멸 |
static 변수 = 클래스 변수 | static 예약어 사용 클래스 내부에 | 클래스 내부에서 사용 -private 이 아니면, 클래스 이름으로 다른 클래스에서 사용 | 데이터 영역 | - 프로그램 처음 시작할 때 상수와 함께 데이터 영역에 생성 - 프로그램 끝날 때 메모리 해제와 함께 소멸 |
static
변수클래스 내부의 여러 메서드에서 사용하는 변수
→ 멤버 변수로 선언하는 것이 좋음
멤버 변수가 너무 많으면?
→ 인스턴스 생성 시 쓸데없는 메모리가 할당되어 메모리 많이 차지
⇒ 상황에 적절하게 변수를 사용해야 함
그렇지만, 멤버변수 안쓰면?
→ 쓸때마다 함수간 매개변수 전달해야됨, 귀찮🤦
⇒ 클래스의 속성이 될 수 있는 애들도 적당히 사용하기 ❗
static
변수라고 private
는 아님public
으로 하면 됨 static {
// 가장 먼저 실행
}
public class Student {
public static String school = "냥냥이 대학교";
String name;
public static Student instance;
static {
if(instance == null) {
studentInstance = new Student("yeppi"); // 하나의 객체 생성
}
}
private Student(String name) {
this.name = name;
}
public void studentInfo() {
System.out.println(name + "의 학교는 " + Student.school);
}
}
그런데, 생성자가 private
으로 막혀 있어서 Student 객체 생성 못할 때. . .
static
블록에서 Student 객체를 생성하여 static
변수인 instance
에 할당
Student a = Student.instance;
System.out.println(a.toString());
a.printInfo();
Student b = Student.instance;
System.out.println(b.toString());
b.printInfo();
Student c = Student.instance;
System.out.println(c.toString());
c.printInfo();
출력결과
static1.Student@149852f9
yeppi의 학교는 냥냥이 대학교
static1.Student@149852f9
yeppi의 학교는 냥냥이 대학교
static1.Student@149852f9
yeppi의 학교는 냥냥이 대학교
👉 세 개의 참조변수가 참조하는 객체의 주소가 모두 동일한 것을 확인할 수 있다!
프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴
static
변수와 메서드를 활용하여 구현
유일한 객체를 제공할 때 사용
생성자는 private으로 선언
private Studnet() {}
클래스 내부에 유일한 private 인스턴스 생성
private static Studnet instance = new Studnet();
외부에서 유일한 인스턴스를 참조할 수 있는 public
메서드 제공
public static Studnet getInstance() {
if( instance == null) {
instance = new Studnet();
}
return instance;
}
-
→ private+
→ public싱글톤의 자세한 개념이나 실습은
디자인 패턴 시리즈 2번 싱글톤 링크를 참고해주세요