
oop포스팅인만큼 예시 코드는 java로 작성하겠습니다.
객체지향 프로그래밍 언어에서는 멤버(변수, 함수)는 선언된 객체에게 그 소유권이 있다.
class ClassA {
public int n;
public ClassA(int _n) {
n = _n;
}
}
class ClassB {
public int n;
public ClassB(int _n) {
n = _n;
}
}
public class Ex {
public static void main(String[] args) {
ClassA objectA = new ClassA(10);
ClassB objectB = new ClassB(20);
ClassC objectA_2 = new ClassA(30);
}
}
objectA.n, objectB.n, objectA_2.n 은 10,20,30으로 모두 다른다.
각 객체의 n변수는 같을까? 다르다.
헷갈릴까봐 접근할 때도 앞에 객체명을 붙여야 접근이 되게 해놓았다. 클래스가 같든 다르든 간에 각 n은 서로 각기 다른 객체에게 소유권이 있다.
static을 붙이면 그 멤버의 소유자가 달라진다. 객체꺼 → 타입꺼
일반적으로 객체는 객체 선언시 heap영역에 객체 단위로 자리잡고, 멤버들도 그 영역에 저장이 되게 된다.
하지만 static 멤버는 클래스의 정보를 저장할 때 따로 static영역이라는 메모리에 직접 저장되고 관리된다.
한 클래스 당 여러 객체를 만들 수 있어서 일반 멤버는 여러개 존재할 수 있지만, static 멤버는 클래스에게 소유권이 있는 정보이기 때문에 클래스 당 하나만 생성된다.
그래서 static 멤버를 클래스 멤버라고도 부른다.
이걸 이해하면 밑의 특징들을 외울 필요가 없다.
객체 선언 없이 바로 클래스에 접근해서 호출할 수 있다.
클래스 내에서 선언 위치 때문에 발생하는 호이스팅관련 문제가 없다.
static메소드 내부에서 (같은클래스더라도) 인스턴스 필드를 참조할 수 없다.
결국 같은 거지만 클래스명으로도, 객체명으로도 접근가능하다. (언어마다 다를 수 있다.)
클래스 정보는 그 클래스 이름이 처음 불렸을 때 메모리에 로딩되고, 프로그램 종료 시 해제된다. 그래서 무분별한 static사용은 메모리를 차지한다는 측면에서 비효율적일 수 있다.
class StaticSample {
public int n;
public void g() {
m = 20; //컴파일러에 따라 다르지만 m이 non_static이였으면 js에서 undefined 에러 발생
}
public void h() {
m = 30;
}
public static int m;
public static void f() {
n = 5; //static 메소드에서 인스턴스 필드 접근 시 컴파일에러
m = 5;
}
}
public class Ex {
public static void main(String[] args) {
StaticSample.m = 10; //객체 선언 없이 바로 접근
StaticSample s1 = new StaticSample();
System.out.println(s1.m); //객체명으로 static변수 접근
s1.f(); //객체명으로 static메서드 접근
StaticSample.f(); //클래스명으로 static메서드 접근
}
등을 활용해서 상수, 싱글톤패턴 등에 활용된다