본문 바로가기
Java

[JAVA] Static

by goblin- 2024. 9. 24.

static 키워드는 자바에서 매우 중요한 개념으로, 클래스와 객체의 메모리 관리와 관련된 중요한 기능을 제공합니다. static을 사용하면 객체가 아닌 클래스 자체에 속하는 변수나 메서드를 정의할 수 있습니다. 이를 통해 메모리를 효율적으로 관리하고, 여러 객체가 공통으로 사용할 수 있는 자원을 제공할 수 있습니다.

 

1. static 키워드란?

 

static 키워드를 사용하면 해당 변수나 메서드는 클래스의 모든 인스턴스에서 공유됩니다. 즉, 객체가 아닌 클래스 자체에 속하는 변수나 메서드를 정의하는 데 사용됩니다.

 

2. static의 특징

 

클래스 로딩 시 메모리에 할당: static 변수나 메서드는 프로그램이 시작될 때 클래스가 로드되면서 메모리에 할당됩니다. 객체가 생성되기 전에 이미 메모리에 존재하게 됩니다.

클래스 수준의 멤버: static으로 정의된 변수나 메서드는 클래스 수준에 존재하며, 객체마다 별도로 생성되지 않습니다.

공유 자원: 클래스의 모든 인스턴스가 동일한 static 변수나 메서드를 공유합니다.

객체 생성 없이 호출 가능: static 메서드나 변수를 사용하기 위해 객체를 생성할 필요가 없습니다. 클래스 이름을 통해 직접 접근할 수 있습니다.

 

3. static 변수 (정적 변수)

 

static 변수는 클래스에 속하는 변수로, 클래스의 모든 인스턴스가 공유하는 변수입니다. 객체마다 별도로 생성되지 않으며, 클래스에 딱 한 번만 메모리에 할당됩니다.

 

예시:

public class Counter {
    public static int count = 0; // static 변수

    public Counter() {
        count++; // 객체 생성 시마다 count 증가
    }
}

public class Main {
    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
        Counter c3 = new Counter();
        
        // static 변수는 클래스 이름으로 접근 가능
        System.out.println("Total objects created: " + Counter.count);
    }
}

출력 결과:

Total objects created: 3

count 변수는 static으로 선언되었기 때문에, 모든 객체가 이 변수를 공유합니다. 따라서 각 객체가 생성될 때마다 count가 증가하고, 마지막에 Counter.count를 출력하면 3이 나옵니다.

 

4. static 메서드 (정적 메서드)

 

static 메서드는 객체가 아닌 클래스에 속하는 메서드입니다. static 메서드는 객체를 생성하지 않고 클래스 이름을 통해 호출할 수 있습니다. 또한, static 메서드에서는 인스턴스 변수나 메서드에 접근할 수 없습니다. 이는 static 메서드가 객체 없이 동작하기 때문에 객체 고유의 필드나 메서드에 접근할 수 없기 때문입니다.

 

예시:

public class MathUtils {
    public static int add(int a, int b) {
        return a + b;
    }
    
    public static int multiply(int a, int b) {
        return a * b;
    }
}

public class Main {
    public static void main(String[] args) {
        // 객체 생성 없이 static 메서드 호출
        int sum = MathUtils.add(5, 10);
        int product = MathUtils.multiply(5, 10);
        
        System.out.println("Sum: " + sum);
        System.out.println("Product: " + product);
    }
}

출력 결과:

Sum: 15
Product: 50

MathUtils 클래스의 addmultiply 메서드는 static으로 선언되었기 때문에 객체를 생성하지 않고 클래스 이름으로 직접 호출할 수 있습니다.

 

5. static 블록 (정적 초기화 블록)

 

static 블록은 클래스가 로드될 때 실행되는 코드 블록입니다. 주로 static 변수를 초기화하는 데 사용됩니다. 클래스가 처음 로드될 때 한 번만 실행됩니다.

 

예시:

public class StaticBlockExample {
    public static int count;
    
    // static 초기화 블록
    static {
        count = 100;
        System.out.println("Static block executed");
    }
    
    public static void displayCount() {
        System.out.println("Count: " + count);
    }
}

public class Main {
    public static void main(String[] args) {
        // static 블록은 클래스 로딩 시 자동 실행
        StaticBlockExample.displayCount();
    }
}

출력 결과:

Static block executed
Count: 100

static 블록은 클래스가 로드될 때 한 번 실행되며, count 변수를 초기화합니다. 이 블록은 클래스가 처음 사용될 때만 한 번 실행됩니다.

 

6. static과 인스턴스의 차이

 

인스턴스 변수/메서드는 각 객체마다 별도로 존재하며, 객체가 생성될 때마다 새로운 값이 할당됩니다.

static 변수/메서드는 클래스에 속하며, 객체에 종속되지 않고 클래스 자체에서 공유됩니다.

 

비교 예시:

public class Example {
    public static int staticCount = 0; // static 변수
    public int instanceCount = 0;      // 인스턴스 변수
    
    public Example() {
        staticCount++; // 모든 객체가 공유
        instanceCount++; // 각 객체마다 개별적으로 관리
    }
    
    public static void printStaticCount() {
        System.out.println("Static Count: " + staticCount);
    }
    
    public void printInstanceCount() {
        System.out.println("Instance Count: " + instanceCount);
    }
}

public class Main {
    public static void main(String[] args) {
        Example obj1 = new Example();
        Example obj2 = new Example();
        
        obj1.printInstanceCount(); // 1
        obj2.printInstanceCount(); // 1
        
        Example.printStaticCount(); // 2
    }
}

출력 결과:

Instance Count: 1
Instance Count: 1
Static Count: 2

staticCount는 클래스 전체에서 공유되므로, 객체가 생성될 때마다 값이 증가하지만, 모든 객체가 동일한 값을 공유합니다.

instanceCount는 각 객체마다 개별적으로 존재하므로, 각 객체에서 값이 독립적으로 유지됩니다.

 

7. static의 주의 사항

 

static 메서드에서는 인스턴스 변수나 메서드를 사용할 수 없습니다. 이는 static 메서드가 객체와 독립적으로 동작하기 때문입니다.

static 변수는 모든 객체가 공유하므로, 모든 객체가 이 변수를 수정할 수 있어 데이터 공유 및 수정에 주의해야 합니다.

클래스가 처음 로드될 때 메모리에 올라가므로, 자원을 너무 많이 사용하는 static 변수나 메서드는 성능에 영향을 줄 수 있습니다.

 

8. static의 활용 사례

 

유틸리티 클래스: 자주 사용되는 기능들을 담은 클래스에서 static 메서드로 제공하는 경우가 많습니다. 예를 들어, java.lang.Math 클래스의 sqrt(), pow()와 같은 메서드가 static으로 정의되어 있습니다.

Math.sqrt(25); // 객체 생성 없이 static 메서드 사용

 

싱글턴 패턴: static 변수를 사용해 클래스의 유일한 인스턴스를 저장하고 관리하는 데 사용됩니다.

public class Singleton {
    private static Singleton instance = new Singleton();
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}

 

상수 선언: static final 키워드를 사용해 클래스 수준에서 변경 불가능한 상수를 선언할 수 있습니다.

public class Constants {
    public static final int MAX_VALUE = 100;
}

 

 

정리

 

static 변수는 클래스에 속하며, 모든 인스턴스가 공유하는 변수입니다.

static 메서드는 클래스에 속한 메서드로, 객체 없이 호출할 수 있으며, 인스턴스 변수나 메서드를 참조할 수 없습니다.

static 블록은 클래스가 로드될 때 한 번만 실행되며, 주로 static 변수 초기화에 사용됩니다.

static은 메모리 효율성을 높이고, 공통된 자원을 관리할 때 유용하게 사용됩니다.

 

static 키워드는 주로 유틸리티 메서드, 싱글턴 패턴, 상수 선언 등에서 널리 사용되며, 객체 간의 공유 자원을 관리하는 데 매우 유용한 도구입니다.

'Java' 카테고리의 다른 글

[Java]Generic(Interface에서의 활용)  (0) 2024.09.28
[Java] Generic  (1) 2024.09.28
[JAVA] 빌더(builder)  (0) 2024.09.24
[JAVA] 예외처리(Exception)  (0) 2024.09.24
[JAVA] 자바의 동작원리(JVM, JRE, JDK)  (0) 2024.09.24