Java - static 키워드

청포도봉봉이·2023년 11월 14일
1

java

목록 보기
4/20
post-thumbnail

static 키워드의 개념과 잘못 사용했을 때 발생할 수 있는 문제에 대해 설명해주세요.


static


static 키워드는 정적 또는 고정된이라는 의미이며, static이라는 키워드를 사용하여 static변수와 static메소드를 만들 수 있는데 다른 말로는 정적필드정적메소드라고 하며 이 둘을 합쳐 정적 멤버라고 한다.

정적 필드와 정적 메소드는 객체에 소속된 멤버가 아니라 클래스에 고정된 멤버이다. 그렇기에 클래스 로더가 클래스를 로딩해서 메모리 메소드 영역에 적재할때 클래스 별로 관리된다. 따라서 클래스의 로딩이 끝나는 즉시 바로 사용할 수 있다.

메소드 영역(Method Area): JVM이 시작할 때 생성되는 영역으로 JVM에 의해 사용된다. 이 영역에는 각 클래스와 인터페이스의 실행에 필요한 바이트 코드, 이름, 데이터 타입, 상수, static 변수, 공유 자원 등이 저장된다.

힙 영역(Heap Area): 모든 객체와 배열이 이 영역에 할당된다. 힙 영역은 JVM의 시작과 동시에 할당되며, 자바 런타임에 동적으로 할당되고 해제된다. 즉, new 키워드를 통해 생성된 객체는 모두 힙 영역에 생성되며, 가비지 컬렉터에 의해 이 영역의 불필요한 객체들이 정리된다.

스택 영역(Stack Area): 스택 영역은 각 스레드가 호출하는 메소드에 대한 정보를 저장하는 영역이다. 메소드가 호출되면 스택 프레임이라는 블록이 스택 영역에 생성되며, 이 블록은 지역 변수, 매개 변수, 중간 연산 결과 등 메소드의 작업을 위한 데이터를 포함한다. 메소드가 작업을 완료하면 해당 스택 프레임은 스택에서 제거된다.

위의 그림과 같이 static 키워드로 생성된 정적멤버들은 Heap 영역이 아닌 static 영역 (Class 영역)에 할당된다. static 영역에 할당된 메모리는 모든 객체가 공유하여 하나의 멤버를 어디서든 참조할 수 있는 장점을 가지지만 가비지 컬렉터의 관리 영역 밖에 존재하기 때문에 static영역에서 있는 멤버들은 프로그램이 종료시까지 메모리에 할당된 채로 존재하게 된다. 그렇기에 static을 너무 남발하게 되면 만들고자하는 시스템에 악영향을 줄 수 있다.


static을 남발하면 어떤 악영향이 생길까?


  • 객체 지향 설계의 이점을 잃어버리게 된다.
    • static을 사용하면 객체 지향의 캡슐화, 상속, 다형성을 활용하기 어려워진다.
      static 메소드는 상속받을 수 없으며 인스턴스 메소드와 다르게 동작한다.
  • 테스트하기 어려워진다.
    • static 메소드나 변수는 보통 전역상태를 나타내기 때문에 테스트시 원하는 상태로 쉽게 변경할 수 없기 때문이다.
  • 메모리 누수의 위험이 있다.
    • static 메서드는 클래스가 메모리에 로딩될때 한 번 초기화되며, JVM이 종료될때까지 메모리를 차지하게 된다. 이렇게 되면 메모리 누수가 발생할 수 있다.

static 멤버들은 어떤 상황에서 사용하는 것이 좋을까?


  1. 유틸리티 클래스. Math, Arrays 같은 유틸리티 클래스의 경우 대부분의 메소드가 static이다. 이런 경우 객체를 생성할 필요 없이 클래스 이름으로 바로 접근할 수 있어 편리하다.
  2. 상수 표현. static final을 사용해 상수를 표현할 수 있다. 이런 상수는 클래스 단위로 관리되며 , 인스턴스마다 값이 달라지지 않는다.
  3. 싱글톤 패턴. 객체를 하나만 생성해야 하는 경우 static을 사용할 수 있다. static 변수로 객체를 저장하고, static 메소드로 접근할 수 있게 된다.

Code


public class Main {
    public static void main(String args[]) {
        System.out.println(Static.staticStr);
        //System.out.println(Static.str); //Non-static field 'str' cannot be referenced from a static context
        Static.staticMethod();

        Static staticInstance = new Static();
        System.out.println(staticInstance.str);
        staticInstance.method();
    }
}
public class Static {
    public static String staticStr = "Hello, I'm static string";
    public String str = "Hello, I'm string";

    public static void staticMethod() {
        System.out.println("Hello I'm static method");
        System.out.println(staticStr);
        //System.out.println(str); //Non-static field 'str' cannot be referenced from a static context
    }

    public void method() {
        System.out.println("Hello I'm method");
        System.out.println(staticStr);
        System.out.println(str);
    }
}

위의 코드에서 staticMethod 살펴보면 static 변수 staticStr는 호출가능하지만 str 변수를 호출하지 못한다.
하지만 method에서는 staticStrstr 둘 다 호출이 가능한 걸 확인할 수 있다.

그리고 Main메소드를 살펴보면 static 메소드나 변수는 클래스명.변수 또는 클래스명.메소드명로 바로 호출할 수 있지만 str, method는 new 연산자를 통한 객체 참조를 통해 호출할 수 있다.

profile
서버 백엔드 개발자

0개의 댓글