1. Static 메서드

static 메서드는 클래스 자체에 속하는 메서드입니다. 이 말은 클래스의 인스턴스를 생성하지 않고도 메서드를 호출할 수 있음을 의미합니다. 즉, 클래스명.메서드명() 형식으로 호출이 가능합니다.

public static int add(int a, int b) {
    return a + b;
}

특징

  • 인스턴스 변수 접근 불가:
    • static 메서드 안에서는 인스턴스 변수(즉, this로 참조되는 클래스의 멤버 변수)에 접근할 수 없습니다. 이는 static 메서드가 특정 인스턴스가 아닌 클래스 레벨에서 동작하기 때문입니다.
  • 클래스 변수와 클래스 메서드만 접근 가능:
    • static 메서드에서는 static으로 선언된 다른 변수나 메서드에만 접근 가능합니다.
  • 인스턴스 생성 없이 호출 가능:
    • 인스턴스를 생성하지 않고도 호출할 수 있기 때문에 유틸리티 메서드나 상태를 가지지 않는 단순한 작업을 처리할 때 유용합니다.

예시

public class MathUtil {
    public static int add(int a, int b) {
        return a + b;
    }
}

// 호출 방법
int result = MathUtil.add(5, 10);

이처럼 MathUtil 클래스의 인스턴스를 만들지 않고 add() 메서드를 호출할 수 있습니다.


2. Static이 없는 메서드 (인스턴스 메서드)

static을 붙이지 않은 메서드는 인스턴스 메서드입니다. 즉, 클래스의 인스턴스를 통해서만 호출할 수 있습니다. 해당 메서드는 클래스의 상태(멤버 변수)에 접근하거나, 클래스의 상태를 변경할 수 있습니다.

public int subtract(int a, int b) {
    return a - b;
}

특징

  • 인스턴스 변수에 접근 가능:
    • 인스턴스 메서드는 클래스의 멤버 변수(인스턴스 변수)에 접근하고 이를 조작할 수 있습니다. this를 사용하여 해당 인스턴스의 상태에 접근할 수 있습니다.
  • 인스턴스가 필요함:
    • 이 메서드를 사용하려면 클래스의 인스턴스를 먼저 생성해야 합니다. 즉, new 키워드를 사용해서 객체를 만든 후 메서드를 호출할 수 있습니다.

예시

public class MathUtil {
    public int subtract(int a, int b) {
        return a - b;
    }
}

// 호출 방법
MathUtil util = new MathUtil();
int result = util.subtract(10, 5);

이 경우 MathUtil 클래스의 인스턴스를 생성한 후에 subtract() 메서드를 호출할 수 있습니다.


3. Static 메서드와 인스턴스 메서드의 차이점 요약

특성 static 메서드 인스턴스 메서드
호출 방법 클래스명.메서드() 인스턴스명.메서드()
인스턴스 필요 여부 필요 없음 필요
인스턴스 변수 접근 불가 가능 (this 사용)
클래스 변수 접근 가능 가능
주요 사용 용도 유틸리티, 상태와 무관한 메서드 클래스의 상태에 의존하는 메서드

4. Static을 사용하면 좋지 않은 예시

스태틱을 사용하지 않는 것이 좋은 예제는 인스턴스별로 다른 상태를 유지해야 할 때입니다. 예를 들어, 은행 계좌를 관리하는 클래스를 생각해볼 수 있습니다. 각 계좌는 고유한 잔액을 가지므로, static 메서드를 사용할 경우 모든 인스턴스가 같은 상태를 공유하게 되어 올바르지 않습니다.

예시: 은행 계좌 관리 클래스

public class BankAccount {
    private String accountHolder;
    private double balance;

    // 생성자
    public BankAccount(String accountHolder, double initialBalance) {
        this.accountHolder = accountHolder;
        this.balance = initialBalance;
    }

    // 잔액을 입금하는 메서드
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    // 잔액을 출금하는 메서드
    public boolean withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
            return true;
        } else {
            return false;
        }
    }

    // 현재 잔액을 반환하는 메서드
    public double getBalance() {
        return balance;
    }

    // 계좌 소유자를 반환하는 메서드
    public String getAccountHolder() {
        return accountHolder;
    }
}

사용 예시


public class Main {
    public static void main(String[] args) {
        // 첫 번째 계좌 생성
        BankAccount account1 = new BankAccount("Alice", 1000.0);
        account1.deposit(500.0);
        System.out.println(account1.getAccountHolder() + "의 잔액: " + account1.getBalance());

        // 두 번째 계좌 생성
        BankAccount account2 = new BankAccount("Bob", 2000.0);
        account2.withdraw(300.0);
        System.out.println(account2.getAccountHolder() + "의 잔액: " + account2.getBalance());
    }
}

결과

Alice의 잔액: 1500.0
Bob의 잔액: 1700.0

설명

여기서 각 BankAccount 인스턴스는 고유한 잔액을 가지며, 이를 인스턴스 메서드를 통해 관리합니다. 만약 deposit(), withdraw(), getBalance() 메서드가 static이었다면 모든 계좌가 동일한 잔액을 공유하게 되어 계좌별로 다른 상태를 유지하는 것이 불가능했을 것입니다.

따라서 각 인스턴스의 상태가 달라야 하거나, 인스턴스별로 다른 동작을 해야 할 때는 static 메서드보다는 인스턴스 메서드를 사용하는 것이 더 적합합니다.


5. 결론

static을 붙인 경우:

이 메서드는 클래스 레벨에서 동작하므로, 인스턴스를 만들지 않고 호출할 수 있습니다. 주로 상태를 변경하지 않는 유틸리티 메서드나 공통 작업을 처리할 때 사용됩니다. 이 경우, 클래스의 인스턴스 변수에 접근할 수 없고, 인스턴스를 만들지 않으므로, 메모리 효율적일 수 있습니다.

static을 붙이지 않은 경우:

인스턴스 메서드로, 인스턴스가 가진 상태(멤버 변수)에 접근할 수 있으며, 이를 활용하여 동작하는 메서드를 정의할 수 있습니다. 이 메서드를 호출하기 위해서는 클래스의 인스턴스가 필요합니다.

따라서 add 메서드가 인스턴스의 상태와 상관없이 항상 동일한 작업을 수행하고, 인스턴스가 필요 없는 메서드라면 static을 붙이는 것이 좋습니다. 반면, 이 메서드가 인스턴스의 상태에 의존하거나 상태를 변경할 필요가 있다면 static을 붙이지 말고 인스턴스 메서드로 사용하는 것이 적합합니다.