우와한 개발자

[Java] 객체지향 프로그래밍 - static 구문, 초기화블록, 싱글톤 디자인 패턴

by 우와한개발자

static은 변수, 정적 초기화 블록(static {}), 클래스 안에 선언된 중첩 클래스에 사용

1. static 변수

  • 객체 생성없이 참조 가능
상황 사용형태 예시
import 없음 패키지명.클래스명.변수명 java.lang.Math.PI
클래스 import 클래스명.변수명 Math.PI
static import 변수명 PI
// 1️⃣ import 없음
double a = java.lang.Math.PI;

// 2️⃣ 클래스 import
import java.lang.Math;
double b = Math.PI;

// 3️⃣ static import
import static java.lang.Math.PI;
double c = PI;

 

2. static 메서드

  • 객체 생성없이 호출 가능
  • static 메서드 안에서는 non-static 멤버(변수/메서드)를 객체 생성없이 직접 참조할 수 없음.(객체 생성하면 참조가능)
  • static 메서드 안에서는 static 변수사용은 가능하나 선언 불가.
⚠️ static 메서드 내 static 변수 선언이 불가능한 이유? 
- static 변수는 클래스 로딩 시점에 생성되는데 객체와 무관하게 하나만 존재하기 때문
- 메서드 안의 변수인 지역변수는 스택영역에 생성되고 호출될 때마다 생성되기 때문 즉, 호출될 때 생성되는 공간(스택영역)에 클래스 로딩시점에 생성되는 변수(static영역)를 둘수 없음.
→ 메모리 영역과 생명주기 차이 때문.
상황 사용 형태 예시
import 없음 패키지명.클래스명.메서드() java.lang.Math.max(1, 2)
클래스 import 클래스명.메서드() Math.max(1, 2)
static import 메서드() max(1, 2)
// 1️⃣ import 없음
int a = java.lang.Math.max(1, 2);

// 2️⃣ 클래스 import
import java.lang.Math;
int b = Math.max(1, 2);

// 3️⃣ static import
import static java.lang.Math.max;
int c = max(1, 2);
⚠️ 일반 import와 import static 차이
일반 import는 타입(type)만 가능 : 클래스, 인터페이스, enum, record, annotation
import static은 일반 타입이 아니라, 그 타입 안의 static 변수/메서드/상수/중첩클래스 가능

 

3. static 초기화 블록

static { ... }
  • 생성자가 실행되기 전에 실행
  • static 변수 초기화에 사용 (static 변수 선언 불가.)
  • 객체를 여러 개 생성해도 한번만 실행 (싱글톤 디자인 패턴)
⚠️  인스턴스 초기화 블록
- static을 제외한 초기화 블록({ })으로 클래스 안에 선언
- 생성자가 호출되기 전에 호출
- 인스턴스 변수 초기화에 사용

 

4. Singleton Design Pattern

  • 클래스의 객체를 하나만 만들도록 제한하는 방법
  • 생성자를 private으로 막아 외부에서 생성 제한
  • 클래스 내부에서 private static으로 자기 자신을 생성
  • public static 메서드로 외부에서 사용하도록 공유.
public class Singleton{
	private static Singleton instance = new Singleton();
	
	private Singleton(){ }; // private 생성자.
	
	public static Singleton getInstance(){ return instance;};
}

 

 

5. static 중첩 클래스

  • 상속 가능
  • 최상위 클래스에는 static 불가
public static class A{ }; // Error

static class B{ }; // Error 

class Outer {

    static class Parent {
        void hello() {
            System.out.println("parent");
        }
    }
}

class Child extends Outer.Parent {

}

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기