final
final 키워드
- 처음 정의된 상태가 변하지 않도록 보장한다.
- class, method, 변수 등 여러 곳에 붙을 수 있다.
final
final + 지역변수
- final을 지역 변수에 설정할 경우, 최초 한번만 할당 가능
- 이후에 변수의 값을 변경하면 컴파일 오류 발생
- final 지역변수를 선언시 바로 초기화한 경우, 이미 값이 할당되없으므로 이후에 값 재할당 불가능
final + 매개변수
- 매개변수에 final이 붙으면 메서드 내부에서 매개변수 값의 변경이 불가능
- 메서드 호출시점에 사용된 값이 끝까지 사용됨
public class FinalLocalMain { public static void main(String[] args) { //final 지역 변수1 final int data1; data1 = 10; //최초 한번만 할당 가능 //data1 = 20; //컴파일 오류 //final 지역 변수2 final int data2 = 10; //data2 = 20; //컴파일 오류 method(10); } //final 매개변수 static void method(final int parameter) { //parameter = 20; 컴파일 오류 } }
final + 멤버변수(필드)
- final을 필드에 사용할 경우, 해당 필드는 한번만 초기화 가능
- final 필드를 초기화하는 방법
- 아래 두가지 방법 중 한가지를 사용하면 된다.
- 생성자 초기화
package final1; // final 필드 - 생성자 초기화 public class ConstructInit { final int value; public ConstructInit(int value) { this.value = value; } }
- 필드 초기화
package final1; // final 필드 - 필드 초기화 public class FieldInit { static final int CONST_VALUE = 10; final int value = 10; }
package final1;
public class FinalFieldMain {
public static void main(String[] args) {
// final 필드 - 생성자 초기화
System.out.println("생성자 초기화");
ConstructInit constructInit1 = new ConstructInit(10); //10
ConstructInit constructInit2 = new ConstructInit(20); //20
System.out.println(constructInit1.value); //10
System.out.println(constructInit2.value); //10
// final 필드 - 필드 초기화
System.out.println("필드 초기화");
FieldInit fieldInit1 = new FieldInit();
FieldInit fieldInit2 = new FieldInit();
FieldInit fieldInit3 = new FieldInit();
System.out.println(fieldInit1.value); //10
System.out.println(fieldInit2.value); //10
System.out.println(fieldInit3.value); //10
// 상수
System.out.println("상수");
System.out.println(FieldInit.CONST_VALUE); //10
}
}
ConstructInit
: 생성자 초기화- 각 인스턴스마다 final 필드에 다른 값 할당 가능
- 이후 변경은 불가능
- 각 인스턴스마다 final 필드에 다른 값 할당 가능
FieldInit
: 필드 초기화- 모든 인스턴스가 같은 값을 가짐
- FieldInit 인스턴스의 모든 value 값이 10이 됨
- 필드 초기화는 필드의 코드에 해당 값이 미리 정해져 있기 때문
- 모든 인스턴스가 같은 값을 사용 -> 메모리 낭비
- JVM에 따라서 내부 최적화를 시도할 수 있다. 하지만, 메모리 낭비를 떠나서 같은 값이 계속 생성되는 것은 중복이다.
- -> static 영역을 사용하자.
- JVM에 따라서 내부 최적화를 시도할 수 있다. 하지만, 메모리 낭비를 떠나서 같은 값이 계속 생성되는 것은 중복이다.
- 모든 인스턴스가 같은 값을 가짐
FieldInit.MY_VALUE
: static final- static 영역에 존재
- final 키워드를 사용했기 때문에 초기화 값이 변하지 않음
- static 영역은 단 하나만 존재. -> MY_VALUE 변수는 JVM 상에 하나만 존재 -> 중복, 메모리 비효율 해결
✏️ 필드에 final + 필드 초기화를 사용하는 경우, static을 붙여서 사용하자.
final static
상수(constant)
: 변하지 않고, 항상 일정한 값을 갖는 수.- Java에서, 단 하나만 존재하며 변하지 않는 고정된 값을 상수라고 칭한다.
- Java 상수의 특징
- static final 키워드를 사용
- 대문자를 사용, _(언더스코어)로 구분
- 일반적인 변수와 구분하기 위함
- 필드를 직접 접근해서 사용
- 상수의 목적은 고정된 값 자체를 사용하는 것! (기능이 목적이 아님)
- 상수의 값 변경은 불가능하다. 따라서, 필드에 직접 접근해도 데이터가 변하는 문제가 발생하지 않는다.
package final1;
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 SECONDS_IN_MINUTE = 60;
// 애플리케이션 설정 상수
public static final int MAX_USERS = 1000;
}
- 일반적으로 상수는 애플리케이션 전반에서 사용됨. -> public 사용
- 특정 위치에서만 사용하는 경우, 다른 접근 제어자를 사용
- 상수는 런타임에 변경 불가능
- 변경하려면 프로그램을 종료해야 함
final 변수와 참조
final + 기본형 변수
: 실제 값 변경 불가능final + 참조형 변수
: 실제 값 변경 가능, 주소값은 변경 불가능
package final1;
public class FinalRefMain {
public static void main(String[] args) {
final Data data = new Data();
//data = new Data(); //final 변경 불가 컴파일 오류
//참조 대상의 값은 변경 가능
data.value = 10;
System.out.println(data.value); //10
data.value = 20;
System.out.println(data.value); //20
}
}
public class Data {
public int value;
}
'Java > 문법' 카테고리의 다른 글
[Java] 우선순위 큐 (PriorityQueue) 기본 사용법부터 객체 다루는 방법까지 (0) | 2024.04.22 |
---|---|
[JAVA 중급 스터디 - 7~9회차] 상속 (0) | 2024.03.20 |
[JAVA 중급 스터디 - 4~5회차] static (0) | 2024.03.20 |
[JAVA 중급 스터디 - 3회차] 자바의 메모리 구조 (0) | 2024.03.09 |
[JAVA 중급 스터디 - 2회차] 접근 제한자와 캡슐화 (0) | 2024.03.08 |