-> 블로그 이전

[Java] static

2021. 11. 19. 16:20Language`/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 사용 불가