[JAVA] static 멤버, static 메소드
static 멤버의 선언
class StaticSample {
int n; // non-static 필드
void g() {....} // non-static 메소드
static int m; // static 필드
static void f() {....} // static 메소드
}
non-static 멤버와 static 멤버의 차이점
non-static 멤버 | static 멤버 | |
공간적 특성 | 멤버는 객체마다 별도 존재 - 인스턴스 멤버라고 부름 |
멤버는 클래스 당 하나 생성 - 멤버는 객체 내부가 아닌 별도의 공간(클래스 코드가 적재되는 메모리)에 생성 - 클래스 멤버라고 부름 |
시간적 특성 | 객체 생성시에 멤버 생성됨 - 객체가 생길 때 멤버도 생성 - 객체 생성 후 멤버 사용 가능 - 객체가 사라지면 멤버도 사라짐 |
클래스 로딩 시에 멤버 생성 - 객체가 생기기 전에 이미 생성 - 객체가 생기기 전에도 사용가능 - 객체가 사라져도 멤버는 사라지지 않음 - 멤버는 프로그램이 종료될 때 사라짐 |
공유의 특성 | 공유되지 않음 - 멤버는 객체 내에 각각 공간 유지 |
동일한 클래스의 모든 객체들에 의해 공유됨 |
static 멤버의 생성과 활용 : 객체.static 멤버
class StaticSample {
public int n;
public void g() {
m = 20;
}
public void f() {
m = 30;
}
public static int m;
public static void f() {
m = 5;
}
}
public class Ex {
public static void main(String[] args) {
StaticSample s1,s2;
s1 = new StaticSample();
s1.n = 5;
s1.m = 50; // static
s2 = new StaticSample();
s2.n = 8;
s2.h();
s2.f(); // static
System.out.println(s1.m);
}
}
static 멤버의 생성
static 멤버가 생성되는 시점은 StaticSample이 사용되기 시작하는 시점(StaticSample 클래스가 로딩되는 시점)
다음 코드가 실행되는 시점에는 멤버 m과 f()는 이미 존재하여 사용 가능
StaticSample s1,s2;
다음 코드는 2개의 StaticSample 객체를 생성하는 코드
s1 = new StaticSample();
s2 = new StaticSample();
static 멤버 m과 f()는 이들 두 객체가 생성되기 전에 이미 생성되어 있으므로, s1과 s2 객체가 생성될 때 인스턴스 멤버인 n, g(), h(0만 객체마다 생성됨
static 멤버 접근
다음 코드는 s1, s2 객체의 static 멤버를 접근
s1.m = 50;
s2.f();
static 멤버 공유
객체 s1과 객체 s2는 static 멤버 m과 f()를 공유하고 또한 자신의 멤버라고 생각함
g(), h()에서도 static 멤버 m을 공유하고 있는 것을 볼 수 있음
static 멤버의 생성과 활용 : 클래스명.static 멤버
class StaticSample {
public int n;
public void g() {
m = 20;
}
public void f() {
m = 30;
}
public static int m;
public static void f() {
m = 5;
}
}
public class Ex {
public static void main(String[] args) {
StaticSample.m = 10;
StaticSample s1;
s1 = new StaticSample();
System.out.println(s1.m);
s1.f();
StaticSample.f();
}
}
static 멤버는 클래스당 하나만 있기 때문에 다음과 같이 클래스 이름으로 바로 접근할 수 있음
StaticSample.m = 10;
static 메소드도 다음과 같이 2가지 방법으로 모두 접근 가능
s1.f(); // 객체 레퍼런스로 static 멤버 f() 호출
StaticSample.f(); // 클래스명을 이용하여 static 멤버 f() 호출
그러나 다음 코드는 잘못됨, non-static 메소드는 클래스 이름으로 접근할 수 없음
StaticSample.h(); // h()는 non-static 이므로 오류
StaticSample.g(); // g()는 non-static 이므로 오류
static의 활용
전역 변수와 전역 함수를 만들 때 활용
자바에서는 C++와 달리 어떤 변수나 함수도 클래스 바깥에 존재할 수 없으며 클래스 멤버로 존재해야함
=> 자바의 캡슐화
static은 모든 클래스에서 공유하는 전역 변수(global variable)나 모든 클래스에서 호출 할 수 있는 전역 함수(global function)가 필요한 경우가 있음
=> static으로 해결
공유 멤버를 만들고자 할 때 사용
static으로 선언된 필드나 메소드는 하나만 생성되어 클래스의 객체들 사이에서 공유됨
class Calc {
public static int abs(int a) {
return a>0 ? a : -a;
}
public static int max(int a, int b) {
return a>b ? a : b;
}
public static int min(int a, int b) {
return a>b ? b : a;
}
}
public class CalcEx {
public static void main(String[] args) {
System.out.println(Calc.abs(-5));
System.out.println(Calc.max(10,8);
System.out.println(Calc.min(-3,-8);
}
}
// 5
// 10
// -8
static 메소드의 제약 조건
static 메소드는 static 멤버만 접근할 수 있다.
static 메소드는 객체 없이 존재하기 때문에, 객체와 함께 생성되는 non-static 멤버를 사용할 수 없고 static 멤버만 사용 가능
반면 non-static 메소드는 static 멤버들을 사용할 수 있음
static 메소드는 this를 사용할 수 없다.
static 메소드는 객체 없이도 존재하기 때문에 this를 사용할 수 없음
출처 : http://www.yes24.com/Product/Goods/61269276