☕ JAVA

[Java] static 키워드

별이⭐ 2024. 5. 3. 08:25

정적(static) 멤버

💡 정적 멤버 = 정적 필드 + 정적 메서드

  • 자바는 클래스 로더(loader)를 이용해서 클래스를 메서드 영역에 저장하고 사용한다.
  • 정적 멤버란 메서드 영역의 클래스에 고정적으로 위치하는 멤버를 말한다.
    • 그렇기 때문에 정적 멤버는 객체를 생성할 필요 없이 클래스를 통해 바로 사용이 가능하다.
  • 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 소속된 멤버이기 때문에 클래스 멤버라고도 한다.

장단점

💡 장점과 단점

  • 장점
    • 모든 인스턴스에서 공유되므로 메모리 관리를 효율적으로 해 메모리 사용량을 줄일 수 있다.
  • 단점
    • 메모리 관리
      • JVM의 메서드 영역은 GC(가비지 컬렉터) 대상이긴 하지만, GC가 메서드 영역을 정리하는 경우가 드물다.
      • 따라서 많은 클래스를 로드하고 이를 장시간 유지하는 애플리케이션은 메모리 누수를 주의해야 한다.
    • 멀티스레드 환경에서의 동기화 문제
      • 멀티스레드 환경에서 여러 스레드가 동시에 static 변수에 접근하면 동시성 문제가 발생할 수 있다.
    • 캡슐화 위반 가능성
      • 캡슐화는 데이터+함수를 하나로 묶어 객체의 세부 정보를 숨기고 필요한 정보만을 제공하는 것을 의미한다.
      • static 멤버는 클래스의 모든 인스턴스에 의해 공유되므로, “객체의 상태는 오직 그 객체의 메서드에 의해서만 변경되어야 한다.”는 캡슐화의 원칙에 위배될 수 있다.

선언

💡 정적 멤버 선언

public class 클래스 {
    // 정적 필드 선언
    **static** 타입 필드 [= 초기값];

    // 정적 메서드 선언
    **static** 리턴타입 메소드( 매개변수, ... ) { ... }
}

 

💡 static 필드 선언

  • 객체마다 가지고 있을 필요가 없는 공통적인 필드(속성)는 static으로 선언하는 것이 좋다.

💡 static 메서드 선언

  • 인스턴스 멤버를 사용하지 않는 메서드를 static 메서드로 선언하는 것이 좋다.
  • static 메서드의 사용
    • 객체 생성이 필요 없다. 클래스이름.메서드이름() 으로 호출한다.
      • ex) Calculator.plus()
  • static 메서드 내에서 인스턴스 변수는 사용할 수 없다.
    • 왜? 인스턴스 변수는 객체 생성 후 호출 가능하기 때문

 

  • static 메서드 내에서 인스턴스 메서드를 호출할 수 없다.
    • 왜? 인스턴스 메서드는 인스턴스 변수를 사용해서 객체가 필요한 메서드인데 static 메서드는 객체 생성 없이도 항상 호출 가능이기 때문에 객체 생성 유무가 불확실함. 그래서 인스턴스 메서드 사용이 불가능하다.

 

  • main() 메서드도 정적 메서드이므로 객체 생성 없이 인스턴스 필드와 인스턴스 메서드를 main() 메서드 내에서 바로 사용할 수 없다!

예시

💡 Calculator로 예시를 들어보자

public class Calculator {
    String color;                                       // 인스턴스 필드
    void setColor(String color) { this.color = color; } // 인스턴스 메소드

    static int plus(int x, int y) { return x+y; }       // 정적 메소드
    static int minus(int x, int y) { return x-y; }      // 정적 메소드
}
  • 예를 들어 plus() 메서드는 외부에서 주어진 매개 값들을 가지고 처리하므로 정적 메서드로 선언하는 것이 좋다.
  • 그러나 인스턴스 필드인 color를 변경하는 setColor() 메서드는 인스턴스 메서드로 선언해야 한다.