본문 바로가기

Java

제어자 (static과 final)

728x90

제어자클래스, 메서드, 혹은 변수 선언부 앞에 붙어서 사용하며 부가적인 의미를 부여하는 역할을 합니다. 제어자는 접근 제어자와 그 외 제어자, 이렇게 크게 2가지로 나눌 수 있습니다.

 

  • 접근 제어자: 멤버 또는 클래스에 사용되어, 해당하는 멤버 혹은 클래스를 외부에서 접근하지 못하도록 제어하는 역할
    • public: 접근 제한이 전혀 없어 어디서든 접근가능
    • protected: 같은 패키지 내, 혹은 다른 패키지의 자손 클래스에서 접근가능
    • default: 같은 패키지 내에서만 접근가능
    • private: 같은 클래스 내에서만 접근가능 
  • 그 외: static, final, abstract, volatile, transient, native, synchronized, strictfp

 

위의 여러 가지 제어자들 중, static과 final에 대해서 자세히 알아보겠습니다.


static

static은 '클래스의', '공통적인'이라는 의미를 내재하고 있습니다. 따라서 인스턴스에 관계없이 모두 같은 값을 가질 수 있습니다. 즉, 인스턴스끼리 공유하는 값이라고 할 수 있겠죠.

 

static이 붙을 수 있는 곳은 멤버변수, 메서드, 초기화 블록이 있습니다.


초기화 블록 및 static 관련 사항은 아래 포스팅에서 더 자세히 나와있으니 참고하세요!

https://silver-programmer.tistory.com/29

 

자바의 변수 (종류 및 초기화)

이번 포스팅은 Java의 기초 개념 중 하나인 변수의 종류와 초기화 방법에 대해서 작성해 보았습니다. 클래스를 이용하여 객체를 생성하고, 객체마다 속성을 정의해 주는 멤버변수(클래스 영역에

silver-programmer.tistory.com


1. static (멤버) 변수

- 해당 클래스의 모든 인스턴스에서 공통적으로 사용하는 변수

- < 클래스. 변수명>으로 접근하여  인스턴스를 생성하기 전에도 사용 가능한 변수 

2. static 메서드

- 해당 클래스를 상속한 자식 클래스는 이 메서드 오버라이딩 불가

- static 메서드 내에서는 인스턴스 변수 사용 불가

- 인스턴스 메서드보다 호출되는 속도가 빠르므로 인스턴스 변수를 사용하지 않는 메서드는 static을 붙이자.

3. static 초기화 블록

- 클래스가 메모리에 로딩될 때 단 한 번만 수행

- 주로 static 변수를 초기화하는 데 사용 

 

추가로, 메서드에 static과 abstract를 함께 사용할 수 없습니다. static메서드는 몸통이 있는 메서드에만 사용할 수 있는데 abstract 메서드는 몸통이 없는 메서드이기 때문입니다. 


final

final은 '마지막의', '변경될 수 없는'의 의미를 내재하고 있고, 거의 모든 곳에서 사용할 수 있습니다.

 

final이 붙을 수 있는 곳은 클래스, 메서드, 멤버변수, 지역변수가 있습니다.

 

1. final 클래스

- 변경될 수 없는 클래스로, 상속 불가 (다른 클래스의 조상이 될 수 없다.)

2. final 메서드

- 변경될 수 없는 메서드로, 오버라이딩으로 재정의 불가

- final 메서드에는 private을 별도로 붙일 필요가 없습니다. 어차피 오버라이딩이 불가능하므로 final 하나만으로도 의미 충분하기 때문입니다.

3. final 변수

- 변경될 수 없는 값으로, 상수

- final이 붙은 인스턴스 변수일 경우에는 생성자를 통해 처음에 한 번 초기화 가능 ==> 인스턴스마다 다른 값을 가질 수 있지만, 한 번 설정되면 각 인스턴스 내에서 변경이 불가

 

추가로, 클래스에 abstract과 final은 함께 사용할 수 없습니다. final은 클래스가 확장 불가능하다는 의미이고 abstract은 상속을 통해 구현이 완료되어야 한다는 의미이기 때문에 서로 대립되는 관계이기 때문이죠.


아래는 static과 final을 이용한 예제코드입니다.


class Animal {
    final int size, legCount; // final 변수
    static int count; // 클래스 변수
    static boolean start; // 클래스 변수

    static {
        start = true;
    } // static 초기화 블럭

    {
        count++;
    } // 인스턴스 초기화 블럭

    Animal(int size, int legCount) {
        this.size = size;
        this.legCount = legCount;
    }

    void makeSound() {
        System.out.printf("My Size is %d. I have %d legs", size, legCount);
    }

}

 

위에서 static 초기화 블록을 이용해 start 변수를 true로 초기에 한 번 실행합니다. 그리고 final 형 변수를 생성자를 통해 초기화해 줍니다. 이 변수는 후에 접근하여 변경이 불가능합니다. 위 클래스의 객체를 만들어서 아래와 같이 호출하면 3개 객체가 생성됨을 확인할 수 있습니다. 


if (Animal.start) { // 클래스 변수 접근
     while (Animal.count < 3) {
          Animal animal = new Animal(30, 4);
       // animal.legCount = 2; 변경 불가
          animal.makeSound();
      }
  }

 

 

 

 

728x90
반응형

'Java' 카테고리의 다른 글

다형성(Polymorphism)  (2) 2023.10.15
추상클래스(Abstract)과 인터페이스(Interface)  (0) 2023.10.15
JVM의 메모리 구조  (0) 2023.10.14
가변인자(varargs)  (0) 2023.10.14
자바의 변수 (종류 및 초기화)  (0) 2023.10.14