공부/Java

자바 final

Stair 2024. 9. 2. 15:43
반응형

final 키워드는 이름 그대로 끝 이라는 뜻이다.

변수에 final 키워드가 붙으면 더는 값을 변경할 수 없다.

 

final은 class, method를 포함한 여러 곳에 붙을 수 있다. 지금은 변수에 붙는 final 키워드이다.

public static void main(String[] args) {
    final int data1;
    data1 = 10; //최초 한번만 할당 가능

    data1 = 20;

	final int data2 = 20;
}

 

final로 data1을 지정해 준 후 최초 한번 10으로 할당한 뒤 20으로 변경을 하면

java: variable data1 might already have been assigned

위와 같은 에러가 발생한다.

final이기에 최초 할당 이후로는 더이상 값의 변경이 불가능 하기 때문이다.

 

매개변수에도 final 키워드를 붙힐 수 있다.

static void method(final int parameter){
    parameter = 20;
}

위와 같은 메소드를 지정할 때 파라미터 값을 final 키워드로 붙히면 메서드 내부에서 값의 변경이 불가능하다.

 

final을 멤버 변수에 사용할 경우

public class ConstructInit {
    final int value;

    public ConstructInit(int value) {
        this.value = value;
    }
}

위 처럼 생성자를 통해서 초기화가 가능하다.

 

또한 멤버변수에 static final이 붙을 경우 상수 취급을 하며 변수명을 대문자로 작성하는 것이 관례이다.

public class FieldInit {

    static final int CONST_VALUE = 10;
    final int value = 10;

    public FieldInit(int value){
        this.value = value;
    }

}

 

위 코드의 CONST_VALUE는 static final이기에 변수명을 대문자로 적어야 한다.

그리고 value는 final이며 생성과 동시에 초기화를 해주었기 때문에 생성자를 통한 변경이 불가능하다.

 

CONST_VALUE와 같은 경우는 static이라 메서드 영역에 만들어지나 value와 같은 경우는 힙 영역에 생성된다.

하지만 final이기에 각 객체에 생성되는 값은 모두 10이게 되며 결과적으로 메모리를 낭비하게 된다.

 

그렇기에 CONST_VALUE와 같은 경우를 상수라고 한다.

상수(Constant)

상수는 변하지 않고 항상 일정한 값을 갖는 수를 말한다. 자바에서는 보통 단 하나만 존재하는 변하지 않는 고정된 값을 상수라한다. 이런 이유로 상수는 static final 키워드를 사용한다.

상수의 특징으로는

1. static final 키워드를 사용한다.

2. 대문자를 사용하고 구문은 _로 한다(관례)

3. 필드를 직접 접근해서 사용한다. (상수는 기능이 아니라 고정된 값 자체를 사용하는 것이 목적이기 때문이다.)

4. 상수는 값을 변경할 수 없다. 따라서 필드에 직접 접근해도 데이터가 변하는 문제가 발생하지 않는다.

 

public class Constant {

    public static final double PI = 3.14;
    public static final int HOURS_IN_DAY = 24;
    public static final int MINUTES_IN_HOUR = 60;
    public static final int SECOND_IN_MINUTE = 60;

    public static final int MAX_USERS = 1000;
}

 

애플리케이션 안에는 다양한 상수가 존재할 수 있다. 수학, 시간 등 고정된 값들이기 때문이다.

보통 이런 상수들은 애플리케이션 전반에 사용되기 때문에 public을 자주 사용한다. 특정 위치에 사용되는 상수라면 접근제어자를 통해 가려주어야 한다.

상수는 중앙에서 값을 하나로 관리할 수 있다는 장점도 있다.

상수는 런타임에 변경할 수 없다. 상수를 변경하려면 프로그램을 종료하고, 코드를 변경한 뒤 다시 실행해야 한다.

 

 

public static void main(String[] args) {
    System.out.println("프로그램 최대 참여자 수 " + 1000);
    int currentUserCount = 999;
    process(currentUserCount++);
    process(currentUserCount++);
    process(currentUserCount++);
    process(currentUserCount++);
}


private static void process(int currentUserCount){
    System.out.println("참여자 수: " + currentUserCount);

    if (currentUserCount> 1000){
        System.out.println("대기자로 등록합니다.");
        return;
    }
    System.out.println("게임에 참여합니다.");
}

 

위와 같이 게임 동시 접속자의 수가 최대 1000명인 프로그램이 있다고 가정하자.

지금까지는 잘 동작하는 프로그램이나, 만약 서버를 증설하여 동시접속자가 최대 2000명이 된다면 어떡해야하나?

위와 같은 코드의 문제는 손볼 곳이 한두군데가 아니라는 점이다. 또 다른 개발자들이 보았을때 1000이 의미하는 뜻을 정확하게 파악하기 어렵다.(이런 문제를 매직 넘버라고 한다)

이러한 코드의 문제는 static final 상수값을 적용하여 상수값 하나만 변경시켜 문제를 해결할 수 있다.

public static void main(String[] args) {
    System.out.println("프로그램 최대 참여자 수 " + Constant.MAX_USERS);
    int currentUserCount = 999;
    process(currentUserCount++);
    process(currentUserCount++);
    process(currentUserCount++);
    process(currentUserCount++);
}


private static void process(int currentUserCount){
    System.out.println("참여자 수: " + currentUserCount);

    if (currentUserCount> Constant.MAX_USERS){
        System.out.println("대기자로 등록합니다.");
        return;
    }
    System.out.println("게임에 참여합니다.");
}

 

즉 상수의 값을 통해 중앙에서 관리할 수 있고, 매직넘버에 대한 문제가 해결된다.

 

마지막 final 예제이다.

public class Data {
    public int value;

}

 

public static void main(String[] args) {
    final Data data = new Data();
    
    //참조 대상의 값은 변경 가능하다.
    data.value = 20;
    System.out.println("data.value = " + data.value);
}

 

참조값이 final로 정의되었으나 참조 대상의 값은 변경이 가능하다.

final은 data에만 걸었기 때문에 data가 참조하고 있는 참조값인 x001(임의의 값이다)을 변경 못한다는 것이지 이 변수 이외에 다른 곳에 영향을 주는 것이 아니다.

 

 

 

반응형

'공부 > Java' 카테고리의 다른 글

자바 다형성 1편 (Polymorphism)  (0) 2024.09.04
자바 상속이란  (1) 2024.09.03
자바 메모리 구조와 static  (2) 2024.09.02
자바 접근 제어자  (5) 2024.08.31
자바 패키지  (0) 2024.08.31