본문으로 바로가기

[Java] 정적 멤버

category Backend/객체 지향 프로그래밍 2022. 4. 9. 13:54

1. 정적 멤버

정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드

정적 메소드, 정적 필드를 클래스 멤버라고 부르기도 합니다.

 

2. 정적 멤버 선언

  • static 키워드를 붙여서 정적 멤버를 선언합니다. (static = 고정된)
  • 정적 멤버는 클래스에 고정된 멤버이므로 클래스 로더가 클래스(바이트 코드)를 로딩해서 메소드 메모리 영역에 적재할 때 클래스 별로  관리
  • 클래스의 로딩이 끝나면 바로 사용 가능
public class 클래스 {
	// 정적 필드
	static 타입 필드 [= 초기값];

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

 

[정적 필드]

객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언하고, 

객체마다 가지고 있을 필요성이 없는 공용적인 데이터라면 정적 필드로 선언

 

[정적 메소드]

인스턴스 필드를 이용해서 실행해야 한다면 인스턴스 메소드로 선언하고, 

인스턴스 필드를 이용하지 않는다면 정적 메소드로 선언

 

3. 정적 멤버 사용

  • 클래스가 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있으며 클래스 이름과 함께 도트(.) 연산자를 이용하여 접근합니다.
  • 객체 참조 변수로도 접근은 가능하지만 정적 멤버는 클래스 이름으로 접근하는 것을 권장합니다.
클래스이름.필드;
클래스이름.메소드( 매개값, ... );

 

예시

public class Computer {
    // 인스턴스 필드
    long serialNumber;

    // 정적 필드
    static String modelName = "Mac Book Air M1";

    // 인스턴스 메소드
    public long getSerialNumber() {
        return serialNumber;
    }

    // 정적 메소드
    public static String getModelName() {
        return modelName;
    }
}
// 정적 필드
String modelName = Computer.modelName;

// 정적 메소드
Computer.getModelName();

 

4. 정적 초기화 블록

  • 정적 필드는 객체 생성 없이도 사용해야 하므로 생성자에서 초기화할 수 없으므로 정적 블록을 제공
  • 주로 복잡한 초기화가 필요할 경우 사용합니다.
  • 정적 블록은 클래스가 메모리로 로딩될 때 자동적으로 실행
  • 클래스 내에 여러 개 선언되어도 상관없습니다. (순서대로 처리)
static {
   ...
}

 

예시

public class Computer {
    // 정적 필드
    static String modelName;

    // 정적 메소드
    public static String getModelName() {
        return modelName;
    }

    // 정적 초기화 블록
    {
        modelName = "Mac Book Air M1";
    }
}

 

주의 사항(정적 메소드, 정적 초기화 블록)

정적 메소드, 정적 초기화 블록 내에서 인스턴스 멤버, this 키워드 사용 불가능

객체가 없어도 접근 가능하다는 특징 때문에 정적 멤버 내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없습니다.

 

정적 메소드와 정적 블록에서 인스턴스 멤버를 사용하고 싶다면 객체를 생성하고 참조 변수로 접근해야 합니다.

 

예시

public class Computer {
    // 인스턴스 필드
    long serialNumber;

    // 정적 필드
    static String modelName;

    // 인스턴스 메소드
    public long getSerialNumber() {
        return serialNumber;
    }

    // 정적 메소드
    public static void printModelNameAndSerialNumber() {
        Computer computer = new Computer();
        computer.serialNumber = 12345;
        System.out.println("serialNumber: " + computer.serialNumber);
        System.out.println("modelName: " + modelName);
    }

    // 정적 초기화 블록
    {
        modelName = "Mac Book Air M1";
    }
}

 

예시(main 메소드)

public class Main {

    String name;

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        //불가능(main 메소드는 정적 메소드 이기 때문)
        // name = "veneas"
        // System.out.println(getName());

        // 객체를 생성해서 접근해야 함
        Main main = new Main();
        main.name = "veneas";
        System.out.println(main.getName());
    }
}