Java

static 메소드 vs 인스턴스 메소드

뽀루피 2024. 7. 17. 00:33

static 메소드와 인스턴스 메소드 항상 사용만 했었는데 왜 그런지는 생각해 본 적이 없었다. 그래서 사용하는 이유에 대해 정리할 필요가 있다고 느껴져 게시물을 작성하게 되었다.

 

static 메소드

static 메소드의 예시

public class MathUtils {
    // static 메소드: 원의 면적 계산
    public static double calculateCircleArea(double radius) {
        return Math.PI * radius * radius;
    }

    // static 메소드: 섭씨를 화씨로 변환
    public static double celsiusToFahrenheit(double celsius) {
        return (celsius * 9/5) + 32;
    }
}

 

static 메소드는

  • 컴파일 시점에 바인딩된다. 즉, 정적 바인딩되고 클래스 로딩 시점에 메모리에 할당된다.
  • 클래스(또는 인터페이스)에 속하며 인스턴스와 무관하다.
  • 오버라이딩이 불가하고, 다형성을 지원하지 않는다.
    • 다형성이란, 하나의 객체가 여러가지 일을 할 수 있는 것을 의미한다. 오버라이딩, 오버로딩 등으로 다형성을 구현할 수 있다.
    • 오버라이딩이 불가한 이유? static 메소드는 클래스나 인터페이스에 직접 연결되어 있어 오버라이딩 할 수 없다.
    • 상속받은 하위 클래스에서 같은 이름의 static 메소드를 정의할 수 있지만, 이것은 오버라이딩이 아니라 메소드 숨김(method hiding)이다. 

 

# 예시

interface MyInterface {
    public static void staticMethod() {
        System.out.println("인터페이스의 static 메소드");
    }
}

class MyClass implements MyInterface {
    // 이것은 오버라이딩이 아닌 새로운 static 메소드입니다.
    public static void staticMethod() {
        System.out.println("MyClass의 static 메소드");
    }
}

public class Main {
    public static void main(String[] args) {
        MyInterface.staticMethod(); // 출력: 인터페이스의 static 메소드
        MyClass.staticMethod();     // 출력: MyClass의 static 메소드

        MyInterface mi = new MyClass();
        // mi.staticMethod(); // 컴파일 에러: static 메소드는 인스턴스를 통해 호출할 수 없음
    }
}

 

 

static 메소드는 인스턴스를 통해 호출될 수 없는 이유

  • static 메소드는 객체의 상태와 무관하게 동작한다.
  • 인스턴스 없이 호출 가능한 static 메소드는 자원을 효율적으로 사용할 수 있다.
  • static 메소드는 설계 원칙에서 클래스 레벨의 기능을 제공하기 위한 것이다.
  • 컴파일러는 static 메소드 호출을 최적화하고 있는데 인스턴스를 통한 호출을 허용하면 최적화가 힘들다.

이러한 이유로 사실상 막아둔 것이다.

 

 

인스턴스 메소드

인스턴스 메소드의 예시

public class Car {
    private String brand;
    private String model;
    private int speed;

    // 생성자
    public Car(String brand, String model) {
        this.brand = brand;
        this.model = model;
        this.speed = 0;
    }

    // 인스턴스 메소드: 속도 증가
    public void accelerate(int increment) {
        this.speed += increment;
        System.out.println("현재 속도: " + this.speed + " km/h");
    }
}

 

인스턴스 메소드는

  • 런타임에 바인딩된다. 즉, 동적 바인딩되고 객체가 생성될 때 메모리에 할당된다.
  • 오버라이딩을 적용할 수 있다. 부모 객체 전체를 바꾸지 않고 자식 객체만 코드를 덮어써 전체 코드에 미치는 영향을 줄일 수 있다.