[Java] static을 언제 사용할까?

재우·2023년 7월 21일
0

Java

목록 보기
1/1
post-thumbnail

Static

Java에서 Static 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미합니다. 이를 정확히 이해하기 위해서는 메모리 영역에 대한 이해가 필요합니다.

일반적으로 우리가 만든 Class는 Static 영역에 생성되고, new 연산을 통해 생성한 객체는 Heap영역에 생성됩니다. 객체의 생성시에 할당된 Heap영역의 메모리는 Garbage Collector를 통해 수시로 관리를 받습니다.
하지만 Static 키워드를 통해 Static 영역에 할당된 메모리는 모든 객체가 공유하는 메모리라는 장점을 지니지만, Garbage Collector의 관리 영역 밖에 존재하므로 Static을 자주 사용하면 프로그램의 종료시까지 메모리가 할당된 채로 존재하므로 자주 사용하게 되면 시스템의 퍼포먼스에 악영향을 주게 됩니다.


Static 사용의 장점

  1. 메모리를 효율적으로 사용이 가능하다. 생성할 때 마다 인스턴스가 힙에 올라가는 것이 아닌 고정 메모리 이므로 보다 효율적이다.

  2. 속도가 빠르다. 객체를 생성하지 않고 사용하기 때문에 속도가 빠르다는 이점이 있다.

Static 사용의 단점

  1. 무분별한 static의 사용은 메모리 유수(Leak)의 원인이 된다. 프로그램 종료 시점에 메모리를 반환하는 속성이 있어 GC(Garbage collection) 대상이 아니기 때문이다.

  2. 재 사용성이 떨어진다. 정적인 값이기때문에 interface를 구현하는데 사용될 수 없다.


Instance 사용의 장점

  1. 재 사용성이 좋다. 언제든지 변할 수 있는 동적인 값이기에 재사용하기 좋다.
  2. 필요에 따라 여러 인스턴스 객체를 생성하여 분리해서 사용할 수 있다. 인스턴스 객체를 개수 제한없이 사용 가능 하기에 분리성이 좋다.

Instance 사용의 단점

  1. 리소스를 많이 잡아먹는다. 사용하기 위해선 인스턴스 객체를 new로 생성해줘야하는데 생성할 때 마다 해당 크기만큼 리소스를 잡아먹기 때문이다.


Static 변수 특징

Static 변수는 클래스 변수입니다. 객체를 생성하지 않고도 Static 자원에 접근이 가능합니다.

public class MyCalculator {
    public static appName = "MyCalculator";

    public static int add(int x, int y) {
        return x + y;
    }

    public int min(int x, int y) {
        return x - y;
    }
}

MyCalculator.add(1, 2);   //  static 메소드 이므로 객체 생성 없이 사용 가능
MyCalculator.min(1, 2);   //  static 메소드가 아니므로 객체 생성후에 사용가능


MyCalculator cal = new MyCalculator();
cal.add(1, 2);   // o 가능은 하지만 권장하지 않는 방법
cal.min(1, 2);   // o

Static 변수(정적 변수)

  • 메모리에 고정적으로 할당되어, 프로그램이 종료될 때 해제되는 변수

Java에서 Static 변수는 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 변수로, 메모리에 한번 할당되므로 여러 객체가 해당 메모리를 공유하게 됩니다.

public class Person {
    private String name = "jaewoo";

    public void printName() {
        System.out.println(this.name);
    }
}

하지만 위와 같은 클래스를 통해 100명의 Person 객체를 생성하면, "jaewoo"라는 같은 값을 갖는 메모리가 100개나 중복해서 생성되게 됩니다. 이러한 경우에 static을 사용하여 여러 객체가 하나의 메모리를 참조하도록 하면 메모리 효율이 더욱 높아질 것입니다.
또한 "jaewoo"라는 이름은 결코 변하지 않는 값이므로 final 키워드를 붙여주며, 일반적으로 static은 상수의 값을 갖는 경우가 많으므로 public으로 선언을 하여 사용합니다.
이러한 이유로, 일반적으로 static 변수는 public 및 final과 함께 사용되어 public static final로 활용 됩니다.

 public class Person {
     public static final String name = "jaewoo";

     public static void printName() {
         System.out.println(this.name);
     }
 }

위의 코드를 보면, printName이라는 함수 역시 static 키워드가 붙어서 static메소드가 되었는데, static 변수는 static 메소드를 통해 접근하도록 권장되기 때문입니다.

Static 메서드(정적 메서드)

  • 객체 생성 없이 "클래스.메서드()" 형태로 호출 하는 방식으로, 인스턴스 멤버와 관련 없는 작업을 하는 메서드이다. 메서드 내에서 인스턴스 변수를 사용할 수 없다.

cf. 인스턴스(Instance) 메서드란?
인스턴스 객체를 생성 후 "인스턴스변수.메서드()" 형태로 호출하는 방식으로, 인스턴스 멤버와 관련된 작업을 하는 메서드이다. 메서드 내에서 인스턴스 변수를 사용할 수 있다.

class Math1 {

    //인스턴스 변수
    int a,b;
    
    // 인스턴스 메서드
    int add(){
    	return a + b;
    }
    
    //static 메서드
    static int add(int a, int b){
    	return a + b;
    }
}


class Main {

	public static void main(String args[]) {
    	
        //static 메서드(클래스 메서드) 호출 => 객체 생성 없이 호출 가능
    	System.out.println(Math1.add(200,100);
                        
        
        //인스턴스 생성
        Math1 mt1 = new Math1(); 
        mt1.a = 200;
        mt1.b = 100;
        
        //인스턴스 메서드 호출
        System.out.println(mt1.add());
    }
}



그렇다면 언제 Static을 붙여서 사용하면 될까? (static 사용 시기)

Card라는 클래스를 만들어 예제로 확인해보자.

class Card{

    /* 인스턴스 변수 (개별 속성) */
    String kind; //카드 종류    
    int number; //카드 번호
    
    
    /* 클래스변수 (공통 속성) */
    static int width = 150; //폭
    static int height = 300; //높이
    
}

개별 속성을 부여해야 하는 카드 종류와 번호의 변수는 인스턴스 변수로 생성을 하고 클래스 내부에서 공통으로 정해져있는 정적인 값을 사용하는 변수는 static으로 사용했다.
이와 같이 정적으로 사용하는 변수는 static을 사용하면 된다.



마지막으로 메서드를 사용할 때는 어떤지 한번 예제로 확인해보자.

class StaticStudyClass{

   void instaceMethod() {} //인스턴스 메서드 생성
   static void staticMethod() {} //static 메서드 생성
   
   //인스턴스 메서드
   void instanceMethodCall(){
   	instanceMethod(); //호출 O
       staticMethod(); //호출 O
   }
   
   //Static 메서드
   static void staticMethodCall() {
   	instanceMethod(); //호출 X (에러 발생 => static메서드는 객체를 생성하지 않기때문에 인스턴스 메서드를 사용할 수 없다.)        
       staticMethod(); //호출 O
   }
   
}
  1. 인스턴스 메서드는 왜 모두 호출이 될까?
    => 인스턴스 메서드를 호출할려면 이미 어딘가에선 해당 클래스를 인스턴스 객체를 생성해 놓았으니 해당 클래스의 모든 부분을 참조 및 호출 할 수 있는것이다.
  1. static 메서드는 왜 인스턴스 변수를 호출하지 못할까?
    => static의 개념을 생각해보면 객체를 생성하지 않는다. 이 개념을 잘 생각해보면 다른 클래스의 인스턴스 객체를 생성하지 않은 상태에서 인스턴스 메서드를 호출하면 에러가 나는 것이 당연하다. 여기서 가장 중요한 것은 인스턴스 객체의 생성 여부이다.

0개의 댓글