본문 바로가기

Java/기본

[Java] 자바 final 키워드의 사용

final 키워드는 변수를 변경할 수 없도록 지정할 때 사용한다. 사전적으로 따져보면 final이란 entity가 단 한 번만 할당될 수 있다고 선언하는 것이라고 한다. final로 초기화한 뒤에 값을 변경하려고 하면 컴파일 에러가 발생한다.


특히 static 과 final을 모두 지정한 필드를 '클래스 상수'라고 부른다. 보통 클래스 상수는 대문자로 기술하여 일반 변수와 구분되도록 한다.

String name = "홍길동";				//일반변수
final String THANKYOU = " 고객님 감사합니다!";	//final 변수

String message = name + THANKYOU;

 


final 키워드는 변수, 메서드, 클래스에 붙일 수 있다

  • final 변수

해당 변수가 생성되고 값이 지정되면, 값이 고정된다.

public class AbsoluteZ {
    public static void main(String[] args) {
        final double absoluteZero = -273.15;
//        absoluteZero = -120;	//값을 변경할 수 없음
    }
}

 

  • final 메서드

메서드에 final이 붙으면 하위클래스에서 오버라이딩을 할 수 없다. 
오버라이딩을 할 수 없다는 것은 즉, 하위클래스에서 재정의하여 상위클래스의 메서드를 숨길 수 없다는 것을 의미한다.

 

코드 예제

Bird 클래스와 이를 상속받는 Sparrow 클래스를 통해 final 의 특성에 대해 알아보자.

 

Bird 클래스

public class Bird {
    final int footCount = 2;
    
    void sing(){
        System.out.println("노래 부른다");
    }
    
    final void fiy(){
        System.out.println("하늘 난다");
    }
    static final void wake(){
        System.out.println("일찍 일어나는 새가 벌레를 잡는다");
    }
}

 

Bird 클래스를 상속받은 Sparrow 클래스

  • sing() 메서드는 오버라이딩해서 메서드를 재정의했다
  • fly() 메서드는 final 키워드가 붙어있으므로 오버라이드 할 수 없다. 메서드를 생성할 수는 있지만 호출시 상위클래스의 메서드가 호출되기 떄문에, fly() 에 작성한 코드는 일종의 dead code가 된다
  • wake() 메서드는 static final 키워드가 붙어있다. 같은 이름의 메서드를 생성하는 것도 불가하다.
public class Sparrow extends Bird{
    @Override
    void sing() {
        System.out.println("나는 꾀꼬리 같은 소리로 아침을 깨우지");
    }
    void fly(){
        //메서드를 선언할 수는 있지만 메서드 명이 동일할 뿐
        //Bird 클래스의 메서드를 오버라이드한 것은 아니다
        System.out.println("이 메서드는 출력 안된다");
    }

//    void wake(){} //오버라이드 불가
}

 

 

 

public class MainEx {
    public static void main(String[] args) {
        Bird bird01 = new Bird();
        bird01.fiy();
        bird01.sing();
        Bird.wake();
        System.out.println();

        Sparrow sparrow = new Sparrow();
        sparrow.fiy();
        sparrow.sing();
        sparrow.wake();
        System.out.println();

        int foot = sparrow.footCount;
        System.out.println("다리 개수 : "+ foot);
    }
}

 

실행 결과

하늘 난다
노래 부른다
일찍 일어나는 새가 벌레를 잡는다

하늘 난다
나는 꾀꼬리 같은 소리로 아침을 깨우지
일찍 일어나는 새가 벌레를 잡는다

다리 개수 : 2

 

 

 

  • final 클래스

클래스에 final이 붙은 경우 안타깝게도 더이상 하위(자손)클래스를 가질 수 없다. 즉, extends 가 허용되지 않는다는 의미이다. 우리가 자주 애용하는 String 클래스가 대표적인 final 클래스이다.

 

 


static final

보통 final 앞에 static 수식자를 붙인 static final 을 선언하여 사용하는 편이 많다. static 으로 선언하면 Java T메모리 static 영역에 할당되어 모든 클래스에서 접근 및 참조할 수 있다. 한번만 객체가 생성되면 다른 클래스에서 중복하여 생성할 필요가 없다. 또한 인스턴스를 생성하지 않고도 접근이 가능해진다. 정리를 해보자면

  • 모든 클래스에서 참조할 수 있고
  • 인스턴스를 생성하지 않고도 접근할 수 있고
  • 값이 고정되어 변경될 우려를 하지 않아도 되는

아주아주 중요한 절대값 1개에 static final 이라고 선언하게 된다.