[Java] Static


Objectives:

  • Static 이란 무엇인가?
  • Static 은 언제 활용되는가? 언제 활용하면 안되는가?

Agenda:

  1. Static 이란?
  2. 클래스 변수와 인스턴스 변수
  3. 클래스 메소드와 인스턴스 메소드
  4. 클래스 멤버와 인스턴스 멤버간 호출 및 참조
  5. 요약

1. Static 이란?

  • 프로그래밍 용어로써 Static 은 정적, 고정의 뜻을 가지고 있다.
  • 프로그래밍 언어마다 조금씩은 다른 의미를 가지고 있으며 Java의 경우, static 이 어떻게 활용되는지 알아보고자 한다.

2. 클래스 변수와 인스턴스 변수

클래스 변수와 인스턴스 변수에 대한 용어 정리를 먼저 해보자.

  • 클래스 변수: 변수 앞에 “static” 이 붙은 변수
  • 인스턴스 변수: 변수 앞에 “static”이 붙지 않은 변수

하나의 예시를 보면서 static 에 대해서 알아 보자.

예시는 총 52개의 Playing Card 를 구현하기 위해 Card 클래스를 선언한다.

  • 클래스 내 데이터(i.e., 변수, 함수)는 카드의 무늬, 숫자, 폭, 높이를 포함한다.
  • 카드의 무늬와 숫자는 인스턴스마다 다른 값을 유지해야 하므로 인스턴스 변수로 설정하고, 카드의 폭과 높이는 모든 인스턴스에 동일하게 적용되는 부분이므로 클래스 변수로 설정한다.
/* Card 클래스 선언 */
class Card {
  String kind; // 카드의 무늬 - 인스턴스 변수
  int number; // 카드의 숫자 - 인스턴스 변수
  
  static int width = 100; // 카드의 폭 - 클래스 변수
  static int height = 250; // 카드의 높이 - 클래스 변수
}

/* Test 클래스 선언 */
class CardTest {
  public void static main(String args[]){
    // Static의 경우 인스턴스 선언없이 바로 사용 가능함
    System.out.println("폭: " + Card.width + ", 높이: " + Card.height);

    // Card 인스턴스 생성
    Card redCard = new Card();
    redCard.kind = "Heart";
    redCard.number = 7;

    // Card 인스턴스 생성
    Card blueCard = new Card();
    blueCard.kind = "Space";
    blueCard.number = 2;

    // redCard 클래스 변수 변경 - 2배 증가
    redCard.width = 200;
    redCard.height = 500;

    // blueCard 출력
    System.out.println("폭: " + blueCard.width + ", 높이: " + blueCard.height);
  }
}

/* 실행 결과 */
폭: 100, 높이: 250
폭: 200, 높이: 500

클래스 변수의 경우 Class 인스턴스의 선언없이 사용 가능하다.

Card.width, redCard.width, blueCard.width 모두 같은 값을 공유한다.

  • 하나의 값이 바뀌면 다른 값도 모두 바뀜 –> 같은 공간을 참조(pointing)한다.
  • 예시처럼 redCard의 attribute를 바꿨는데도 blueCard의 attribute 값도 바뀐다.

3. 클래스 메소드와 인스턴스 메소드

호출을 할 때에도 클래스 변수처럼 인스턴스 생성 필요없이 바로 활용할 수 있다.

예를 들면, 다음과 같이 활용할 수 있다.

Class.Method

그럼 언제 static 을 활용하여 메소드를 정의하는지 알아보자.

  • 클래스 (class)는 변수(variable)와 함수(method)의 집합체
  • 인스턴스 메소드는 해당 메소드를 수행하기 위해서 인스턴스 변수를 활용
  • 따라서 어떤 메소드에서 인스턴스 변수를 활용하지 않거나, 클래스 변수 또는 매개 변수로 메소드를 활용한다면 클래스 메소드로 정의
  • 인스턴스 변수를 활용하지 않는다고 해서 클래스 메소드로 무조건 정의하는것은 아님
  • 예시는 Math 클래스가 있음
    • 모든 작업을 매개 변수로만 진행함

4. 클래스 멤버와 인스턴스 멤버간 호출 및 참조

같은 클래스 내 멤버들간에는 별도의 인스턴스를 생성하지 않고도 서로 호출 및 참조 가능하다.

단, 클래스 멤버가 인스턴스 멤버를 호출 및 참조하고자 하는 경우에는 인스턴스를 생성해야 한다.

그 이유는 인스턴스 멤버가 클래스 멤버를 호출하는 시점에는 클래스 멤버의 존재가 보장되지만, 클래스 멤버가 인스턴스 멤버를 호출하는 시점에는 인스턴스 멤버의 존재가 보장되지 않는다.

클래스 멤버 (i.e., 변수, 메소드)는 언제나 호출 및 참조 가능하다.

따라서, 클래스 멤버 > 클래스 멤버, 인스턴스 멤버 > 클래스 멤버는 언제나 가능하다.

더불어, 인스턴스 멤버 > 인스턴스 멤버 역시 언제나 가능하다.

하지만, 인스턴스 멤버 > 클래스 멤버는 클래스 멤버의 인스턴스 생성이 필요하다.

/* Example */
class MemberCall{
  int instance_variable_1 = 10;
  int class_variable_1 = 20;

  // 인스턴스 변수는 클래스 변수를 사용할 수 있음
  int instance_variable_2 = class_variable_1 // instance_variable_2: 20

  // 클래스 변수는 인스턴스 변수를 바로 사용할 수 없음
  static int class_variable_2 = instance_variable_1 // ERROR
  
  // 굳이 사용하려면 인스턴스를 생성해야 함
  static int class_variable_2 = new MemberCall().instance_variable_1 // class_variable_2: 10

  // 클래스 메소드 생성
  static void classMethod_1(){
    System.out.println(class_variable_1); // 20
    System.out.println(instance_variable_1); // ERROR
    MemberCall mc = new MemberCall();
    System.out.println(mc.instance_variable_1); // 10
  }
}

5. 요약

  • 클래스 설계 시, 멤버 변수 중 모든 인스턴스에서 공통적으로 활용하는 변수는 static 을 적용함
    • 기본적으로 생성된 인스턴스는 서로 독립적이며 다른 공간을 참조하기 때문에 다른 값을 유지함
    • 경우에 따라 각 instance 가 공통적으로 같은 값이 유지되어야 하는 경우 static 을 활용함
  • 클래스 멤버는 인스턴스를 생성하지 않아도 사용할 수 있음
    • 클래스 멤버는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성됨
  • 클래스 메소드에서는 인스턴스 변수를 직접적으로 사용할 수 없음
    • 클래스 메소드에서는 인스턴스없이 클래스 멤버를 호출 가능함
    • 반면, 인스턴스 메소드에서는 인스턴스 생성 후 클래스 멤버를 호출 가능함
    • 인스턴스 변수가 존재한다는 것은 static이 붙은 변수가 이미 메모리에 존재한다는 것을 의미함
  • 메소드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려함
    • 메소드의 작업 내용 중에서 인스턴스 변수를 필요로 한다면 static 을 붙일 수 없음
    • 반대로 인스턴스 변수를 필요로 하지 않는 다면, static을 붙이는 것이 좋음
      • 메소드의 호출 시간이 짧아지기 때문에 효율이 높아짐
      • static을 안붙은 메소드는 실행 시 호출되어야 할 메소드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸림
  • 클래스 설계 시 static의 사용 지침
    • 먼저 class 의 멤버 변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴보고 있으면 static 을 붙임
    • 작성한 메소드 중에서 인스턴스 변수를 사용하지 않는 메소드에 대해서 static을 붙임

Reference:

  • http://rockdrumy.tistory.com/214
  • http://minche.tistory.com/52





© 2018. by kdohyeon

Powered by kdohyeon