2021. 11. 19. 16:20ㆍLanguage`/Java
※ Example (눈, 공기)
눈
- 사람마다 각자의 차이가 존재
- non-static 멤버
공기
- 모든 사람이 공유
- 오직 1개만 존재
- static 멤버
class StaticSample{
int n; // non-static 필드
void g(){...} // non-static 메소드
static int m; // static 필드
static void f(){...} // static 메소드
static 멤버
- 객체를 생성하지 않고도 사용 가능
- 클래스당 하나만 생성되는 멤버 (클래스 멤버) -> 동일한 클래스의 모든 객체들이 공유
- main() 메소드가 실행되기 전에 이미 생성
- static 멤버의 생성 시점 ≒ JVM 시작 시점
non-static 멤버
- 객체가 생길 때 객체마다 생성 -> 다른 객체들과 공유 X
- 객체가 사라지면 non-static멤버도 함께 사라진다 -> 더 이상 접근 X
- 각 객체마다 하나씩 생성 (인스턴스 멤버)
non-static 멤버 | static 멤버 | |
선언 | class Sample{ int n; void g(){...} } |
class Sample{ static int m; static void f(){...} } |
공간적 특성 | ● 객체마다 별도로 존재 ≫ 인스턴스 멤버 |
● 클래스당 하나 생성 ≫ 멤버는 객체 내부가 아닌 별도의 공간(클래스 코드가 적재되는 메모리)에 생성 ≫ 클래스 멤버 |
시간적 특성 | ● 객체 생성 시 멤버 생성 ≫ 객체 생성 후 멤버 사용 가능 ≫ 객체가 사라지면 멤버도 사라짐 |
● 클래스 로딩 시에 멤버 생성 ≫ 객체가 생기기 전에 이미 생성 ≫ 객체가 생기기 전에도 사용 가능 ≫ 객체가 사라져도 멤버는 사라지지 않음 ≫ 멤버는 프로그램이 종료될 때 사라짐 |
공유의 특성 | ● 공유 X ≫ 멤버는 객체 내에 각각 공간을 유지 |
● 공유 O ≫ 동일한 클래스의 모든 객체들에 의해 공유 |
※ Example) static 멤버 활용 / 접근
1. 객체.static 멤버
StaticSample s1 = new StaticSample();
StaticSample s2 = new StaticSample();
s1.m = 50; // static멤버 m에 접근
s1.g(); // non-static 메소드 g()에 접근
s2.f(); // static 메소드 f()에 접근
s2.h(); // non-static 메소드 h()에 접근
2. 클래스명.static 멤버
- non-static 메소드는 클래스 이름으로 접근 X
StaticSample.m = 10; // static 멤버 m에 접근
StaticSample.f(); // static 메소드 f()에 접근
----------------------
StaticSample.g(); // 오류 -> non-static 메소드에는 클래스이름으로 접근 X
StaticSample.h(); // 오류 -> non-static 메소드에는 클래스이름으로 접근 X
static 활용/제약 조건
활용 1) 전역 변수, 전역 함수를 만들 때
- 자바에서는 어떠한 변수/함수도 클래스 바깥에 존재 X (자바의 캡슐화 원칙)
-> 이러한 문제 해결 : 전역 변수, 전역 함수
※ Example) java.lang.Math 클래스 (static 멤버 보유)
public class Math{
public static int abc(int a);
public static double cos(double a);
public static int max(int a, int b);
public static double random();
...
}
------------------------------
Math m = new Math(); // 오류 -> Math()는 static으로 선언되어 있기 때문에 객체 생성 X
int n = m.abc(-5);
------------------------------
int n = Math.abs(-5); // 정상 작동
활용 2) 공유 멤버를 만들고자 할 때
- static으로 선언된 필드/메소드는 하나만 생성 -> 클래스의 객체들 사이에서 공유
제약조건 1) static 메소드는 static 멤버만 접근 가능
- static 메소드는 객체 없이 존재
-> 객체와 함께 생성되는 non-static 멤버를 사용 X / static 멤버만 사용 O
- non-static 메소드는 static 멤버 사용 가능
∴
static -> non-static : 오류
static -> static : 정상
non-static -> static : 정상
non-static -> non-static : 정상
class StaticMethod{
int n;
static int m;
void f1(int x){n=x;} // 정상 : non-static 메소드 -> non-static 필드
void f2(int x){m=x;} // 정상 : non-static 메소드 -> static 필드
static void s1(int x){n=x;} // 오류 : static 메소드 -> non-static 필드
static void s2(int x){f1(3);} // 오류 : static 메소드 -> non-static 메소드
static void s3(int x){m=x;} // 정상 : static 메소드 -> static 필드
static void s4(int x){s3(3);} // 정상 : static 메소드 -> static 메소드
제약조건 2) static 메소드는 this를 사용할 수 없다
- static 메소드는 객체 없이 존재하기 때문에, this를 사용할 수 없다
class StaticAndThis{
int n;
static int m;
void f1(int x){this.n=x;} // 정상 : non-static -> non-static
void f2(int x){this.m=x;} // 정상 : non-static -> static
static void s1(int x){this.n=x;} // 오류 : static 메소드에서 this 사용 불가
static void s2(int x){this.m=x;} // 오류 : static 메소드에서 this 사용 불가