본문 바로가기
Study/java

Java, 인스턴스 메소드(instance methods)와 정적 메소드(static methods)의 차이

by 유경호 2022. 4. 1.
반응형

개요

메소드를 사용할 때 우리는 보통 두 가지 방식을 채용하여 사용한다. 인스턴스를 생성한 뒤, 그 인스턴스를 참조하여 메소드를 사용하던가 (e.g. instance.someMethod()) 혹은 클래스명으로 메소드를 참조하여 사용하던가(e.g. ClassName.someMethod()) 하여 사용한다.

이 두 방식의 메소드를 각각 인스턴스 메소드(Instance Method), 정적 메소드(Static Method)라고 하며 이 글에서는 이 두 메소드 타입에 대해 알아보고 비교해볼 것이다.

Instance Method

인스턴스 메소드(Instance Method)는 소위 우리가 일반적으로 정의하고 사용하는 메소드이다. 호출하기 위해서는 반드시 해당 메소드가 정의되어 있는 클래스의 객체를 먼저 생성해주어야 한다.

public void myMethod(String name)
{
 // 실행될 코드....
}
// Return type은 int, float String or user defined data type으로 정의될 수 있음.

 

메모리 할당(Memory allocation)

인스턴스 메소드는 컴파일 과정에서 Metaspace(자바8 아래에서는 Permanent Generation)라는 특별한 메모리 영역에 담긴다. 그러나 메소드에 구성된 파라미터(parameter), 지역 변수(local variable), 반환 값(return value)들은 stack 영역에 할당된다.

 

특징

  • 인스턴스 메소드는 클래스의 객체에 속해있는것이지 클래스에 속해있는 것이 아니다. 즉 클래스로 객체를 생성하고서 그 객체를 통해서만 호출할 수 있다.
  • 인스턴스 메소드라고 해서 매번 객체가 생성될 때마다 함께 생성되는 것이 아니다. 메모리에 한 번 할당이되고 각 생성된 객체들은 그 메소드가 메모리 어디에 존재하는지를 알 뿐이다. 객체가 메모리가 할당된 메모리 주소를 담고 있어 메소드를 호출하면 메모리 주소를 통해 메소드를 호출하게 된다.
  • 오버라이드(override)가 가능하다. 런타임(runtime)중 동적 바인딩(dynamic binding)을 통해 메소드의 타입이 결정된다.

Example

// 인스턴스 메소드(instance method) 호출 예시
import java.io.*;

class Foo {

    String fooName = "";

    // 인스턴스 메소드(Instance method)는 접근 제한자가 무엇이 붙었냐에 따라
    // 같은 클래스 내부 혹은 같은 패지키 내부, 다른 패키지의 클래스에서 호출이 가능하다.e.
    public void changeName(String name) { this.fooName = name; }
}

class Bar {
    public static void main(String[] args)
    {

        // 클래스를 통해 instance 생성.
        Foo instance = new Foo();

        // 객체를 통해 인스턴스 메소드(instance method) 호출.
        instance.changeName("Instance of Foo");
        System.out.println(instance.fooName)
    }
}

Output

Instance of Foo

 

Static Method

정적 메소드(static method)는 클래스로 객체를 생성하지 않아도 호출이 가능한 메소드다. 정적 메소드는 해당 메소드가 정의되어 있는 클래스의 이름이나 생성된 객체 통해 호출할 수 있다.

public static void myStaticMethod(String name)
{
 // 실행될 코드....
}

// 반드시 static 수식어(modifier)를 붙여 정의해야 한다.
// Return type은 int, float String or user defined data type으로 정의될 수 있음.

 

메모리 할당(Memory allocation)

정적 메소드(static method)는 정적 메소드가 속한 클래스와 함께 컴파일 과정에서 Metaspace(자바8 아래에서는 Permanent Generation)라는 특별한 메모리 영역에 담긴다. 그리고 정적 메소드에 구성된 파라미터(parameter), 지역 변수(local variable), 반환 값(return value)들은 stack 영역에 할당된다. 정적 메소드가 클래스와 함께 메모리에 올리간 이후로는 객체를 생성할 필요 없이 정적 메소드를 호출할 수 있게 된다.

 

특징

  • 정적 메소드는 메소드가 정의된 클래스에 속해 있는것으로 취급된다. 객체를 생성하여 호출할 필요 없이 클래스명을 통해 참조하여 호출할 수 있다. e.g. ClassName.methodName(args).
  • 같은 클래스를 통해 생성된 객체들간 같은 코드를 사용하는 것을 보장하기 위해 사용된다.
  • 정적 메소드는 오버라이드(Override)될 수 없다. 컴파일 과정에서 정적 바인딩(static binding)되어 메소드 타입이 정해진다.
    • 부모클래스, 자식클래스 간 같은 이름의 메소드를 정의할 순 있다. 하지만 Method Hiding으로 인해 항상 상위 클래스의 정적 메소드만 호출된다.

Example

// 정적 메소드(Static method) 호출 예시
import java.io.*;

class Foo {

    public static String fooName = "";

    public static void changeName(String name)
    {
        fooName = name;
    }
}

class Bar {
    public static void main(String[] args)
    {

        // 클래스명을 통해 정적 메소드(static method) 호출
        Foo.changeName("static called");
        System.out.println(Foo.fooName);

        // 객체를 통해 정적 메소드(static method) 호출.
        Foo instance = new Foo();
        instance.changeName("instance called");
        System.out.println(instance.fooName);
    }
}

Output

static called
instance called

참고: 정적 변수(static variables)와 그 값(primitives or refrences)들은 속해있는 클래스 메모리(Metaspace 내)에 저장된다.

 

static 변수가 다른 객체를 참조한다면 어떻게 될까?

static int i = 1;
static Object obj = new Object();

먼저 1번째 줄의 value인 1은 Metaspace에 저장된다. 그리고 2번째 줄에서 참조 변수은 obj는 Metaspace에 저장되나 Object 클래스의 객체는 heap 영역에 적재된다. 참조 변수 obj에 담기는 Object의 참조값(메모리 주소)는 Metaspace에 저장된다.

 

Instance method vs Static method

  • 인스턴스 메소드(Instance methods)는 인스턴스 메소드(Instance methods)와 인스턴스 변수(instance variables)를 직접 호출할 수 있다.
  • 인스턴스 메소드(Instance method)는 정적 변수(static variables)와 정적 메소드(static methods)를 직접 호출할 수 있다.
  • 정적 메소드(Static methods)는 정적 변수(static variables)와 정적 메소드(static methods)를 직접 호출할 수 있다.
  • 정적 메소드(Static methods)는 인스턴스 메소드(instance methods)와 인스턴스 변수(instance variables)를 호출할 수 없다. 그들은 반드시 객체를 통해 참조해야 한다. 그리고 정적 메소드(static methods)는 this keyword를 사용할 수 없다. this로 참조하기 위한 객체가 존재하지 않기 때문이다.

정리

  • 인스턴스 메소드와 정적 메소드는 메모리 측면에서는 동일하게 Metaspace라는 특수한 영역에 저장된다. 즉 인스턴스 메소드라고 해서 새로운 객체가 생성될 때마다 함께 생성되어 할당되지 않는다.
  • 정적 메소드는 해당 정적 메소드가 정의된 클래스로부터 생성된 객체들이 같은 코드를 실행하는 것을 보장하기 위해 사용한다.
  • 정적 메소드는 오버라이드가 불가능하며 절차지향적인 성향이 강하다. 즉 무분별하게 사용하면 객체지향적인 프로그래밍을 해칠 수 있다.

정적 메소드는 정적 팩토리 메서드 방식과 같이 잘 활용하면 프로그램의 구조를 더욱 더 발전시킬 수 있다. 인스턴스 메소드와 정적 메소드의 차이를 잘 이해하여 상황에 맞게 적용하는 것이 중요하다.


참조

반응형