[Java] Final & Static Final

반응형
반응형

Java 언어에서 Final, Static Final Keyword를 사용하면 상수를 선언할 수 있다.

이번 포스팅 에서는 Final Kewyord와 Static Final Keyword에 대해 알아볼 예정이다.


#1 Final

- Final & Value

- Final & Method

- Final & Class

- Final 필드의 접근 제어자 설정

#2 Static Final

 

* 해당 포스팅은 개인적인 공부 기록 용도로 작성한 글 이기에 잘못된 내용을 포함하고 있을 수 있으며,

혹여나 틀린 정보가 있다면 언제든지 댓글로 남겨주세요!


#1 Final

- Final & Value 

Final Keyword가 붙은 변수는 처음 값을 할당한 후로 값을 변경할 수 없으며, 관례적으로 변수명을 대문자와 단어 사이를 언더스코어(_)로 구분하여 작성한다. 

final int MAX_VALUE = 10; // 재할당 불가능

 

- Final & Method

Final Keyword가 붙은 메서드는 해당 메서드를 오버라이딩 할 수 없도록 설정된다. 

    public fianl void FinalMethod(){
        System.out.println("FinalMethod: 해당 메서드는 오버라이딩이 불가능합니다.");
    }

 

- Final & Class

Final Keyword가 붙은 클래스는 해당 클래스를 상속할 수 없도록 설정된다. 주로 클래스의 불변성을 유지하기 위해 사용되곤 한다. 

public final class FinalTest{
    // ...
}

 

- Final 필드의 접근 제어자 설정 

보통 클래스 내부의 필드의 접근 제어자를 선언할 때 OOP의 캡슐화를 지키기 위해서 해당 필드를 private 접근 제어자로 막아둔 뒤, getter & setter 메서드를 새롭게 정의하여 필드에 접근하는 방식을 사용하곤 한다.  

다음 코드는 Slime 클래스의 level, hp 필드의 접근제어자를 private로 설정하여 외부로부터의 수정을 막아둔 뒤, level 필드에 접근할 수 있는 getLevel 메서드와 hp 필드에 접근할 수 있는 getHp 메서드를 선언한 예제이다. 

package project;

public class Slime{
    private int level; // private member field
    private int hp; // private member field
    
    // priavate level field에 접근하기 위한 getter
    public int getLevel(){
        return this.level;
    }
    
    // priavate hp field에 접근하기 위한 getter
    public int getHp(){
        return this.hp;
    }
   
    // constructor
    public Slime(int level, int hp){
        this.level = level;
        this.hp = hp;
    }
}
package project;

public class Main {
    public static void main(String[] args) {
        Slime normalSlime = new Slime(10, 5);
        int level = normalSlime.getLevel();
        int hp = normalSlime.getHp();
        System.out.println("Slime level : " + level);
        System.out.println("Slime hp : " + hp);
    }
}
Slime level : 10
Slime hp : 5

 

그러나 final 필드외부로 부터의 접근을 막아 두지 않아도 괜찮다. 왜냐하면 final로 선언된 변수는 어차피 처음 초기값을 재설정 할 수 없을 뿐더러, 고정된 값 그 자체를 사용하는 데 의미가 있기에 접근 제어자를 public으로 열어 둔다.

public class Slime{
    private int level; // private member field
    private int hp; // private member field
    public final int FINAL_VALUE; // public final member field
    // getter
    // ...
}

#2 Static Final 

그러나 Final 만으로 변수를 선언하는 것은 약간의 문제가 있다. 

만약 해당 클래스의 값을 모든 객체에서 동일하게 사용하는 경우에는 특정 클래스의 인스턴스를 여러개 생성 한다고 하더라도, 어차피 Final 변수의 값은 하나로 고정되기에 불필요한 메모리 참조가 생기기 때문이다.

따라서 Final 변수 앞에 Static 키워드를 붙여 참조값이 저장되는 Heap 영역이 아닌 공통 데이터를 관리하는 Method 영역에 Final 변수를 할당해 두는 것이 메모리 측면에서 효율적이다. 

(Heap 영역과 Method 영역에 관련한 내용은 다음 포스팅에서 다룬 바가 있습니다. [Java] 메모리 구조 & 스태틱 변수, 메서드 완벽 정리 )

 

이처럼 final keyword 앞에 static keyword가 붙은 변수를 "상수" 라고 부른다. 

요약하자면 final + 필드 초기화를 동시에 진행하는 경우에는 처음부터 static keyword와 함께 사용하여 메모리 누수를 막도록 하자.

public class FinalExample{
    public final int FINAL_VALUE; // 모든 인스턴스가 같은 값을 참조한다. -> 메모리 낭비
    public static final int STATIC_FINAL_VALUE // 인스턴스가 여러개 생성되도 하나의 값을 가리킨다. 
    // ...
}

 


반응형

댓글

Designed by JB FACTORY