본문 바로가기

JAVA 스터디

[JAVA] static과 final

final 키워드는 static과 함께 사용하는 경우가 있습니다.

final은 '최종'의 의미로 더 이상 변경이 불가능하도록 만들고, static은 '정적'이란 의미로

인스턴스 간에 데이터 공유가 필요해서 클래스 멤버로 선언할 때 사용합니다.

 

final 멤버 변수가 반드시 상수는 아닙니다. 즉, 클래스 내/외부로 단 하나의 상수가 아니란 말입니다.

단 하나의 상수란 원주율과 같은 불변의 상수를 말합니다. 이해를 돕기 위해 다음의 예제를 살펴보겠습니다.

 

class Student {
    final String name;
    int age;
    
    public Student(String name) {
        this.name = name;
        this.age = 20;
    }
    public void Info() {
        System.out.println("Name : " + name + ", Age : " + age);
    }
}

public class Example {
    public static void main(String[] args) {
        // 학생 정보 입력
        Student s1 = new Student("Minsu");
        Student s2 = new Student("John");
        
        // 학생 정보 출력
        s1.Info();
        s2.Info();
    }
}

// 실행결과
Name : Minsu, Age : 20
Name : John, Age : 20

 

예제에서 학생의 이름별로 인스턴스를 생성해주고, 그 정보를 출력해주고 있습니다.

Student 클래스의 필드로 name 변수가 final로 지정되었습니다.

final로 지정되어 name은 상수가 되어야 하는데 값이 변경되어 출력되고 있습니다.

 

final만 사용하면 인스턴스 별로 서로 다른 값을 지닐 수 있기 때문에 단 하나의 상수를 정의할 수 없습니다.

 

그러면 왜 static과 final을 함께 사용해야 하는지 되짚어 보겠습니다.

클래스에서 사용할 해당 멤버 변수의 데이터와 그 의미, 용도를 고정시키기 위해서 두 키워드를 함께 사용합니다.

해당 클래스를 쓸 때 변하지 않고 계속 일관된 값으로 쓸 것을 멤버 상수로 지정하는 것입니다. 예를 들어

  • 도형 원을 만드는 클래스에서 약 3.14의 값을 항상 지녀야 하는 원주율 변수
  • 성적 클래스에서 100점이 만점이라고 한다면 100이라는 최대 점수

위의 값들은 모든 클래스 인스턴스에서 동일한 값으로 사용되고, 절대로 변하지 않도록 설계될 것입니다.

인스턴스가 만들어질 때마다 메모리를 생성해서 값을 초기화시키지 말고,

클래스 레벨에서 한 번만 생성 및 초기화해서 사용하면 효율적일 것입니다.

 

public static final int PI = 3.14;
public static final int MAX_SCORE = 100;

 

따라서 위와 같이 선언해줍니다.

이때 static final이라고 작성해도 되고, final static이라고 작성해도 무방합니다.

 

그러나 아래의 링크에 작선된 문서에 따르면,

8.3.1 - Classes - Field Modifiers of the Java Language Specification

 

Chapter 8. Classes

 

docs.oracle.com

필드 선언에 둘 이상의 (고유한)필드 수정자가 표시되는 경우 필드 수정자에 대한 프로덕션에서 위에 표시된 순서와 일치하는 순서로 표시되는 것이 일반적입니다.

 

라고 명시하고 있습니다.

즉, 자바에선 다음과 같은 순서로 수정자를 작성해줄 것을 권장하고 있습니다.

@Annotation public protected private static final transient volatile