자바(Java) 강의

15. 자바 final 키워드

삐멜 2019. 4. 28. 03:03

이번 포스트에서는 final 키워드에 대해서 알아본다.

이전 포스트

목표

  • final 키워드
  • final 변수
  • final 메서드
  • final 클래스 

final 키워드

final 키워드의 의미는 매우 간단하다. final이 변수나 메서드나 클래스 앞에 붙으면, 해당 엔티티(변수/메서드/클래스)는 변경할 수 없는 엔티티가 된다. 실습을 통해 좀 더 알아보자.

final 변수

public class Main {
public static void main(String[] args) {
final String MESSAGE = "Hello World!";
System.out.println(MESSAGE);
}
}

위와 같은 코드를 실행시키면 "Hello World!"가 출력될 것이다. 이 변수의 내용을 변경해보자.

public class Main {
public static void main(String[] args) {
final String MESSAGE = "Hello World!";
MESSAGE = "yo";
System.out.println(MESSAGE);
}
} //Error:(4, 9) java: cannot assign a value to final variable MESSAGE

'Error:(4, 9) java: cannot assign a value to final variable MESSAGE'라는 에러가 난다. 무슨 에러인가? final변수인 MESSAGE에는 값을 할당할 수 없다는 뜻이다. MESSAGE가 final로 선언되었기 때문이다.

public class TutorialClass {
private final String TUTORIAL_VALUE;

}

위처럼 클래스의 바디 안에 멤버상수로 tutorialValue를 선언했다. 하지만 에러가 날 것이다. 왜? 초기화를 해주지 않았기 때문이다. 이 상수를 초기화하는 방법에는 두가지가 있다.

public class TutorialClass {
private final String TUTORIAL_VALUE = "initial value";

}

첫번째는 위처럼 값을 바로 넣어주는 방법이다. 이 방법은 보통 String, int, double등 처럼 진짜 '상수'로 사용할 때 많이 쓴다. 그리고 이런 상수의 경우 보통 대문자와 '_'의 조합으로 상수의 이름을 만들어 준다.

두번째 는 생성자를 이용하는 방법이다.

public class TutorialService {
}

위와같이 빈 서비스 클래스가 있다고 치자.

public final class TutorialClass {
private final TutorialService tutorialService;

public TutorialClass(TutorialService tutorialService) {
this.tutorialService = tutorialService;
}
}

서비스 오브젝트의 경우 대부분 생성자에서 초기화해주고 절대 변경하지 않고 사용한다. final로 선언된 변수는 생성자의 내부에서만 초기화 될 수 있다.

public final class TutorialClass {
private final TutorialService tutorialService = new TutorialService();

public TutorialClass(TutorialService tutorialService) {
this.tutorialService = tutorialService;
}
} //Error:(5, 13) java: cannot assign a value to final variable tutorialService

생성자에서 초기화 하려 하더라도, 이미 초기화되어있는 상태이면 다른 오브젝트를 할당하는것이 불가능하다. 

final 메서드

public class TutorialClass {
public final void tutorialMethod() {
System.out.println("tutorialMethod");
}
}

메서드의 앞에 final을 붙이면 무슨 의미일까? 바로 어느 서브 클래스도 이 메서드를 오버라이드(Override)할 수 없다는 뜻이다.

public class TutorialChildClass extends TutorialClass{
@Override
public final void tutorialMethod() {
System.out.println("tutorialChildMethod");
}
} //Error:(3, 23) java: tutorialMethod() in TutorialChildClass cannot override //tutorialMethod() in TutorialClass overridden method is final

위처럼 TutorialClass를 상속받는 TutorialChildClass를 만들고 Override를 시도해 보면 위처럼 메서드가 final이므로 override를 할 수 없어 에러가 난다.

final 클래스 

이제 final에 대한 감이 좀 잡힐 것이다. final은 그것이 무엇이든 수정하지 못하게 하는 것이다. 그렇다면 final이라고 써있는 클래스는 어떠한가?

public final class TutorialClass {
private final String TUTORIAL_VALUE = "initial value";
}

final클래스는 바로 어떤 다른 클래스도 이 클래스를 상속할 수 없다는 뜻이다. 아래처럼 상속을 시도해보자.
public class TutorialChildClass extends TutorialClass{

} //Error:(1, 41) java: cannot inherit from final TutorialClass

위처럼 final 클래스를 상속할 수 없다는 에러를 확인 할 수 있다.

final은 이처럼 변경하면 안되는 것을 지정할 때 쓴다. 실수로라도 누가 절대로 변경하지 못하게 하기 위함이다. final은 보통 상수나 변경하면 안되는 서비스등에 많이 사용한다.

다음 포스트:16. 자바 변수와 오브젝트와 Null