Post

static

static 이란?

  • 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미한다.

static의 메모리

  • 일반적으로 우리가 만든 class는 static 영역에 생성되고, new 연산을 통해 생성한 객체는 heap 영역에 생성된다.
  • GC는 Heap 영역의 메모리를 관리하기 때문에 영역 밖인 static을 자주 사용하면 프로그램 종료까지 메모리가 할당된 채로 존재하므로 자주 사용하면 시스템 성능에 악영향을 미친다.


static 멤버 특징

  • static 변수는 클래스 변수이다.
  • 객체를 생성하지 않고도 static 자웡에 접근이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Example {
  public static String test = "테스트";

  public static int add(int x, int y){
    return x + y;
  }

  public int min(int x, int y){
    return x - y;
  }
}

Example.add(1, 2);  // static 메소드 이므로 객체 생성 없이 사용 가능
// Example.min(1, 2);  // static 메소드가 아니므로 객체 생성 후에 사용 가능

Example cal = new Example();
cal.add(1, 2);  // 가능은 하지만 권장되지 않는다.
cal.min(1, 2);


객체에서 static 멤버의 사용을 지양하는 이유

  1. 명시성과 가독성
    • static 멤버는 클래스 레벨에서 관리되므로 모든 인스턴스에 공통이다.
    • 만약 인스턴스를 통해 static 멤버에 접근하면 이 멤버가 해당 인스턴스에 속한 것인지, 클래스에 속한 것인지 명확하지 않아 코드의 가독성이 떨어진다.
  2. 유지보수성
    • 인스턴스를 통해 static 멤버에 접근하는 코드가 많아질수록, static 멤버의 수정에 따른 리팩토링 작업이 많아진다.
  3. 멀티스레딩 문제
    • static 변수는 여러 스레드에 의해 동시에 접근될 수 있으므로 동시성 관리가 제대로 이루어져야 한다.
  4. 객체지향 설계원칙 위배
    • 객체지향 프로그램은 데이터와 그 데이터를 처리하는 메서드를 객체로 캡슐화하는데 중점을 둔다.
    • static 변수는 모든 인스턴스에서 공유되므로 객체별 상태를 유지하지 않는다.
    • 때문에 인스턴스를 통한 static 멤버 접근은 객체지향 설계의 기본 원칙과 어긋난다.


static 변수와 static 메소드의 활용

  • static 멤버의 올바른 사용법은 static 멤버들만 모여있는 클래스를 따로 만드는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public final class Constants{
  public static final int ONE = 1;
  public static final int FOUR = 4;
}

public final class CalculateUtils{
  public static int add(int a, int b){
    return a+b;
  }
  public static int min(int a, int b){
    return a-b;
  }
}

System.out.println(CalculateUtils.min(Constants.ONE, Constants.FOUR));  // -3


인터페이스의 static 메소드 허용

인터페이스의 변수는 상수만 허용하기에 항상 public static final 키워드가 붙는다.

  • java 8부터 인터페이스에 default 메소드와 static 메소드의 사용이 허용되었다.
  • 허용 이유는 다음과 같다.
  1. 유틸리티 메소드 제공
    • static 메소드를 인터페이스에 포함시키면, 해당 인터페이스와 관련된 유틸리티 또는 헬퍼 메소드를 제공할 수 있다.
    • 이로 인해 코드의 재사용성 향상과 명확한 분류가 가능해졌다.
  2. 인터페이스의 명확한 책임 분리
    • static 메소드를 통해 인터페이스는 구현체가 아니라도 독립적인 기능을 제공할 수 있다.
    • 이는 인터페이스를 더 유연하게 만들고, 구현 클래스에서 중복되는 유틸리티 메소드를 줄일 수 있게 한다.
  3. 기존 코드와의 호환성 유지
    • 기존에 인터페이스를 구현하던 클래스에 영향을 주지 않으면서 새로운 기능을 인터페이스에 추가할 수 있다.


누군가가 물어본다면

static 키워드는 클래스 레벨에서 공유되는 변수, 메서드, 블록을 정의하는 데 사용되며 Garbage Collector의 관리 대상이 아닙니다.
java 8부터 인터페이스에서 static 메소드가 허용되어 인터페이스를 더 유연하게 만들었습니다.
This post is licensed under CC BY 4.0 by the author.