[Java] 정적(Static) 멤버 (정적 필드와 정적 메서드)

seonwoo·2026년 1월 31일

Java

목록 보기
8/12

1. 정적(Static) 멤버?

Java에서 정적 멤버(static member)
static 키워드가 붙어 객체 생성 여부와 상관없이 클래스에 소속되는 멤버를 말한다.

즉, 객체(new)를 생성하지 않아도 사용할 수 있고
클래스 로딩 시점에 JVM에 의해 메모리의 Method 영역에 올라가고
프로그램 종료 시까지 유지된다.


정적 멤버에는 대표적으로 다음 두 가지가 있다.

  • 정적 필드(static field)
  • 정적 메서드(static method)
class Example {
    static int count;          // 정적 필드
    static void printCount() { // 정적 메서드
        System.out.println(count);
    }
}

이들은 모두 객체가 아닌 클래스에 속한다는 공통점을 가진다.




2. 정적 필드

정적 필드는 나의 클래스에 대해 단 하나만 존재하며
해당 클래스에서 생성된 모든 인스턴스가 이 값을 공유한다.

따라서 객체를 여러 개 생성하더라도
정적 필드는 객체마다 새로 만들어지지 않고
클래스 기준으로 하나의 값이 유지된다.

다음 예제를 살펴보자.

public class A_StaticField {
    // 정적 필드
    // 정적 필드는 클래스가 로드될 때 생성되고 프로그램이 종료될 때 소멸된다.
    public static int number = 101;

    private static String message = "Hello World";

    // 정적 필드에 대한 Getter, Setter 메서드도 static 키워드를 사용해서 접근한다.
    public static String getMessage() {
        return message;
    }

    public static void setMessage(String message) {
        // 정적 필드는 객체를 생성하지 않고 접근하기 때문에 this로 접근할 수 없음
        // this.message = message;
        A_StaticField.message = message;
    }
}

public class Application {
    public static void main(String[] args) {
        // 1. 정적 필드 테스트
        // 1-1). 정적 필드 생성 및 출력
        System.out.println(A_StaticField.number);			// 101
        System.out.println(A_StaticField.getMessage());		// "Hello World"
        System.out.println();

        // 1-2). 객체의 정적 필드 공유 
        A_StaticField a1 = new A_StaticField();
        A_StaticField a2 = new A_StaticField();
		
        // 객체 참조를 통한 접근 (컴파일 가능하지만 권장 X)
		System.out.println(a1.number);	// 101
		System.out.println(a2.number);	// 101
		// 클래스 이름을 통한 접근 (권장)
		System.out.println(A_StaticField.number);	// 101 
        System.out.println();

        // 1-3). 정적 필드의 Getter, Setter 메서드
        A_StaticField.setMessage("Goodbye World");
        System.out.println(A_StaticField.getMessage());	// "Goodbye World"
}

2-1. 정적 필드 특징

클래스 이름으로 접근 가능

System.out.println(A_StaticField.number);			// 101
System.out.println(A_StaticField.getMessage());		// "Hello World"

객체를 생성하지 않아도 바로 사용할 수 있다.



객체 간 값 공유

A_StaticField a1 = new A_StaticField();
A_StaticField a2 = new A_StaticField();

// 객체 참조를 통한 접근 (컴파일 가능하지만 권장 X)
System.out.println(a1.number);	// 101
System.out.println(a2.number);	// 101
// 클래스 이름을 통한 접근 (권장)
System.out.println(A_StaticField.number);	// 101 

A_StaticField.number는 두 객체가 같은 값을 바라본다.
→ 정적 필드는 인스턴스별로 새로 생성되지 않는다.



정적 필드에 대한 Getter / Setter

// 정적 필드에 대한 Getter, Setter 메서드도 static 키워드를 사용해서 접근한다.
public static String getMessage() {
    return message;
}



this 키워드 접근 불가 → 클래스 이름을 사용하여 접근

public static void setMessage(String message) {
    // 정적 필드는 객체를 생성하지 않고 접근하기 때문에 this로 접근할 수 없음
    // this.message = message;
    A_StaticField.message = message;
}    




3. 정적 메서드

정적 메서드는 객체를 생성하지 않고 클래스 이름으로 호출 가능한 메서드이다.

정적 메서드 역시 여러가지 특징을 가지고 있다.
다음 예제를 살펴보자.

public class B_StaticMethod {
	// 정적 필드
    private static int num1 = 10;
    private static int num2 = 18;
    // 인스턴스 필드
    private int num3 = 30;

    // 1. 매개 변수와 반환값이 없는 정적 메서드
    public static void method01() {
        System.out.println(num1 + num2++);

        // 정적 메서드에서는 인스턴스 필드에 접근할 수 없다.
        // 정적 메서드는 객체를 생성하지 않고 사용하므로 인스턴스 필드에 접근할 수 없다.
        // System.out.println(num3);
    }

    // 2. 매개 변수가 없고 반환값이 있는 메서드
    public static int method02() {
        int num1 = 20;
        int num2 = 30;

        // 정적 메서드에서는 this 키워드를 사용할 수 없다.
        // 따라서, B_StaticMethod.num1 형태로 접근한다.
        return num1 + num2 + B_StaticMethod.num2;
    }

    // 3. 매개 변수가 있고 반환값이 없는 메서드
    public static void method03(int number) {
        // 정적 메서드 안에서 다른 정적 메서드를 호출할 수 있다.
        // 단, 정적 메서드 안에서 일반 메서드는 호출할 수 없다.
        // this와 마찬가지로 객체를 생성하지 않고 사용하기 때문이다.
        // ex). sum(number);
        System.out.println(B_StaticMethod.method02() + number);
    }

    private int sum(int number) {
        return number + this.num3;
    }

    // 4. 매개 변수와 반환값이 있는 정적 메서드
    public static int method04(int... numbers) {
        return Arrays.stream(numbers).sum();
    }
}

public class Application {
    public static void main(String[] args) {
		// 2.정적 메서드 테스트
        // 2-1). 매개 변수와 반환값이 없는 정적 메서드 호출
        B_StaticMethod.method01();	// 28
        B_StaticMethod.method01();	// 29
        System.out.println();

        // 2-2). 매개 변수가 없고 반환값이 있는 정적 메서드 호출
        System.out.println(B_StaticMethod.method02());	// 70

        // 2-3). 매개 변수가 있고 반환값이 없는 정적 메서드 호출
        B_StaticMethod.method03(100);	// 170
        System.out.println();
        
        // 2-4). 매개 변수와 반환값이 있는 정적 메서드 호출
        System.out.println(B_StaticMethod.method04());
        System.out.println(B_StaticMethod.method04(4, 5, 15));
        System.out.println(B_StaticMethod.method04(4, 5, 15, 25, 35));
        System.out.println();
}



3-1. 정적 메서드 특징

정적 메서드에서는 인스턴스 필드에 접근할 수 없다.

public class B_StaticMethod {
	// 정적 필드
    private static int num1 = 10;
    private static int num2 = 18;
    // 인스턴스 필드
    private int num3 = 30;
    
    public static void method01() {
        System.out.println(num1 + num2++);
    
        // 정적 메서드에서는 인스턴스 필드에 접근할 수 없다.
        // 정적 메서드는 객체를 생성하지 않고 사용하므로 인스턴스 필드에 접근할 수 없다.
        // System.out.println(num3);
    }
}



정적 메서드에서는 this 키워드를 사용할 수 없다.

public class B_StaticMethod {
    // 정적 필드
    private static int num1 = 10;
    private static int num2 = 18;
    // 인스턴스 필드
    private int num3 = 30;

    public static int method02() {
        int num1 = 20;
        int num2 = 30;

        // 정적 메서드에서는 this 키워드를 사용할 수 없다.
        // 따라서, B_StaticMethod.num1 형태로 접근한다.
        return num1 + num2 + B_StaticMethod.num2;
    }
}



정적 메서드 안에서 일반 메서드는 호출할 수 없다.

public class B_StaticMethod {
    public static void method03(int number) {
        // 정적 메서드 안에서 다른 정적 메서드를 호출할 수 있다.
        // 단, 정적 메서드 안에서 일반 메서드는 호출할 수 없다.
        // this와 마찬가지로 객체를 생성하지 않고 사용하기 때문이다.
        // ex). sum(number);
        System.out.println(B_StaticMethod.method02() + number);
    }

    private int sum(int number) {
        return number + this.num3;
    }
}



4. 정적 멤버를 사용하는 대표적인 예제

// Java.lang.Math
public class Application {
    public static void main(String[] args) {
        // 객체 생성 없이 호출 가능
        int max = Math.max(10, 20);
        double sqrt = Math.sqrt(16);

        System.out.println("최대값: " + max);   // 최대값: 20
        System.out.println("제곱근: " + sqrt); // 제곱근: 4.0
    }
}
profile
Github : https://github.com/melly8954

0개의 댓글