final이라는 키워드는 말 그대로 끝을 의미하며 자바에서는 더는 값을 변경할 수 없다는 뜻을 가지고 있다.
final은 class와 method를 포함한 여러 곳에 붙을 수 있다.
이 포스팅에는 변수의 붙는 final에 대하여 알아볼 것이다.
1. 지역 변수
public class FinalLocalMain {
public static void main(String[] args) {
//final 지역 변수1
final int data1;
data1 = 10; // 최초 1번만 할당 가능
// data1 = 20; // 컴파일 오류
//final 지역 변수2
final int data2 = 10;
// data2 = 20; //컴파일 오류
method(10);
}
static void method(final int paramether){
// paramether = 20; //컴파일 오류
}
}
final을 통해 변수에 값을 할당하게 되면, 그 후 다른 값을 할당해 줄 수 없다.
매개변수에 final이 붙는 경우에도, 매개변수의 값을 변경할 수 없다.
2. 필드(멤버 변수)
public class ConstructInit {
final int value;
public ConstructInit(int value){
this.value = value;
}
}
final을 필드에 사용할 경우, 생성자를 통해서 한번만 초기화가 가능하다.
public class FieldInit {
static final int CONST_VALUE = 10;
final int value = 10;
}
final필드를 필드에서 초기화하면, 이미 값이 할당되었기 때문에 생성자를 통해 초기화 할 수 없다.
또, static 변수에도 final이 선언 가능하다.
3. 상수
상수란, 변하지 않고 항상 일정한 값을 갖는 수다. static final 키워드를 사용하고, 필드를 직접 접근해서 사용한다.
관례 : 대문자를 사용하고 단어의 구분은 _로 한다.
public class ConstantMain1 {
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("대기자로 등록합니다.");
}else{
System.out.println("게임에 참여합니다.");
}
}
}
/*실행 결과
프로그램 최대 참여자 수 1000
참여자 수 : 999
게임에 참여합니다.
참여자 수 : 1000
게임에 참여합니다.
참여자 수 : 1001
대기자로 등록합니다.
참여자 수 : 1002
대기자로 등록합니다.
*/
위 코드는 프로그램의 최대 참여자 수 1000명이 넘는 상태에서 게임에 참여하면 대기자로 등록되는 프로그램이다.
만약 2000명으로 변경해야 한다면?
위 코드에서는 변경해야할 포인트가 2곳이 생기는 것이다. 아래의 코드를 보자.
public class Constant {
public static final double PI = 3.14;
public static final int HOURS_INT_DAY = 24;
public static final int MINUTES_IN_HOUR = 60;
public static final int SECONDS_IN_MINUTE = 60;
//애플리케이션 설정 상수
public static final int MAX_USERS = 2000;
}
public class ConstantMain2 {
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("대기자로 등록합니다.");
}else{
System.out.println("게임에 참여합니다.");
}
}
}
Constant 클래스에 MAX_UESRS라는 상수를 선언 및 초기화 해주고, main에서 클래스를 통해 접근한다.
만약 3000명으로 변경을 하려면, Constant 클래스의 MAX_USERS의 값만 변경해주면 된다.
4. final 변수와 참조
기본형 변수의 값은 변경 못하는 것을 알겠지만, 참조형 변수의 경우 어떻게 할까?
참조형 값의 경우 변수에 할당되어있는 참조값(주소)를 변경하지 못하게 된다.
public class Data {
public int value;
}
public class FinalRefMain {
public static void main(String[] args) {
final Data data = new Data();
// data = new Data(); //컴파일 에러
//참조 대상의 값은 변경 가능
data.value = 10;
System.out.println(data.value);
data.value = 20;
System.out.println(data.value);
}
}
main에서 final객체를 생성하고, 또 그 변수에 다른 객체를 생성하려하면 컴파일 에러가 뜬다.
즉, 참조값(주소값)은 변경될 수 없다는 뜻이다.
하지만 Data클래스의 필드인 value에는 final이 붙지 않았기 때문에 value 값은 변경할 수 있다.
정리하자면 final이 붙은 변수의 값만 변경할 수 없다는 것이다. 참조형 변수면 참조값을 변경 불가하고, 기본형 변수면 변수의 값을 변경할 수 없다는 뜻이다.
'JAVA' 카테고리의 다른 글
| [자바/JAVA] 부모 참조(Super, Super Class) (0) | 2024.06.14 |
|---|---|
| [자바/JAVA] 상속(Inheritance) (0) | 2024.06.14 |
| [자바/JAVA] Static변수와 Static메서드 (0) | 2024.06.13 |
| [자바/JAVA] 자바 메모리 구조와 스택(Stack) (1) | 2024.06.13 |
| [자바/JAVA] 접근 제어자(Access Modifier)와 캡슐화(Encapsulation) (2) | 2024.06.12 |