Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- java
- TIL
- 알고리즘
- Interceptor
- puppeteer
- Kubernetes
- LifeCycle
- css
- 인접행렬
- 탐욕법
- GraphQL
- Deep Dive
- node.js
- nestjs
- 자료구조
- Linux
- Spring
- OOP
- dfs
- 인접리스트
- bean
- javascript
- 프로그래머스
- html
- JWT
- REST API
- winston
- typescript
- MySQL
- 코딩테스트
Archives
- Today
- Total
처음부터 차근차근
[Java] final 본문
728x90
Final이란?
Final 키워드는 말 그대로 '마지막의' 또는 '변경될 수 없는' 의미를 가지고 있으며, 이름 그대로 끝이라는 뜻입니다.
거의 모든 대상에 사용될 수 있습니다.
Final이 사용될 수 있는 대상
- Class
- 변경할 수 없는 클래스, 즉, 확장될 수 없는 클래스를 의미합니다.
- 즉, 다른 클래스의 조상이 될 수 없습니다.
- Method
- 변경될 수 없는 메서드를 의미하며, Overriding을 통해 재정의 될 수 없습니다.
- 멤버 변수, 지역 변수
- 변수 앖에 final이 붙으면, 값을 변경할 수 없는 상수가 됩니다.
- 재할당을 할 경우, 컴파일 오류가 발생합니다.
Final 사용해보기
지역변수
package final1;
public class FinalLocalMain {
public static void main(String[] args) {
// final 지역 변수
final int data1;
data1 = 10; // 최초 한번만 할당 가능
// data1 = 20; // compile 오류
final int data2 = 10;
// data2 = 20; // 컴파일 오류
method(10);
}
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;
}
}
- final을 필드에 사용할 경우 해당 필드는 생성자를 통해서 한번만 초기화 될 수 있습니다.
package final1;
public class FieldInit {
static final int CONST_VALUE = 10;
final int value = 10;
}
- final 필드를 필드에서 초기화하면 생성자를 통해서도 초기화 할 수 없습니다.
- 코드에서 보는 것 처럼 static 변수에도 final을 선언할 수 있습니다.
package final1;
public class FinalFieldMain {
public static void main(String[] args) {
//final 필드 - 생성자 초기화
System.out.println("생성자 초기화");
ConstructInit constructInit1 = new ConstructInit(10);
ConstructInit constructInit2 = new ConstructInit(20);
System.out.println(constructInit1.value);
System.out.println(constructInit2.value);
//final 필드 - 필드 초기화
System.out.println("필드 초기화");
FieldInit fieldInit1 = new FieldInit();
FieldInit fieldInit2 = new FieldInit();
FieldInit fieldInit3 = new FieldInit();
System.out.println(fieldInit1.value);
System.out.println(fieldInit2.value);
System.out.println(fieldInit3.value);
//상수
System.out.println("상수");
System.out.println(FieldInit.CONST_VALUE);
}
}
실행 결과
- FieldInit과 같이 final필드를 필드에서 초기화 하는 경우, 모든 인스턴스가 다음 오른쪽 그림과 같이 같은 값을 가진다.
- 여기서는 FieldInit 인스턴스의 모든 value값은 10이 된다.
- 왜냐하면 생성자 초기화와 다르게 필드 초기화는 필드의 코드에 해당 값이 미리 정해져있기 때문이다.
- 모든 인스턴스가 같은 값은 값을 사용하기 때문에 결과적으로 메모리를 낭비하게 된다.(물론 JVM에 따라서 내부 최적화를 시도할 수 있다) 또 메모리 낭비를 떠나서 같은 값이 계속 생성되는 것은 개발자가 보기에 명확한 중복이다. 이럴 때 사용하면 좋은 것이 바로 static 영역이다.
상수(Constant)
상수란 변하지 않고, 항상 일정한 값을 갖는 수를 의미합니다.
자바에서는 보통 단 하나만 존재하는 변하지 않는 고정값을 상수라 하며, 이런 이유로 상수는 static final 키워드를 사용합니다.
자바 상수 특징
- static final 키워드를 사용합니다.
- 대문자를 사용하고 구분은 _(언더스코어)로 합니다.
- 필드는 직접 접근해서 사용합니다.
- 상수는 기능이 아니라 고정된 값 자체를 사용하는 것이 목적입니다.
- 상수는 값을 변경할 수 없기 때문에, 필드에 직접 접근해도 데이터가 변하는 문제가 발생하지 않습니다.
- 상수들은 애플리케이션 전반에서 사용되기 때문에 public를 자주 사용하지만, 특정 위치에서만 사용해야 할 경우 다른 접근 제어자를 사용하면 됩니다.
상수 예시
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;
}
final 변수와 참조
참조형 데이터 타입을 가진 변수에 Final을 붙인다면, 그 안에 있는 참조값도 변하지 않을까요??
package final1;
public class Data {
public int value;
}
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);
data.value = 20;
System.out.println(data.value);
}
}
참조형 변수 data에 final이 붙었고, 변수 선언 시점에 참조값을 할당했으므로 더는 참조값이 변경할 수 없습니다.
단, 참조 대상의 객체 값은 변경할 수 있습니다.
- 참조형 변수 data 에 final이 붙었다. 이 경우 참조형 변수에 들어있는 참조값을 다른 값으로 변경하지 못한다. 쉽게 이야기해서 이제 다른 객체를 참조할 수 없다. 그런데 이것의 정확한 뜻을 잘 이해해야 한다. 참조형 변수에 들어있는 참조값만 변경하지 못한다는 뜻이다. 이 변수 이외에 다른 곳에 영향을 주는 것이 아니다.
- Data.value는 final이 아니다. 따라서 값을 변경할 수 있다.
- 즉, 참조형 변수에 final이 붙으면 참조 대상 자체를 다른 대상으로 변경하지 못하는 것이지, 참조하는 대상의 값은 변경할 수 있다.
참조
자바의 정석_기초편
'Language > Java' 카테고리의 다른 글
[Java] abstract 추상 클래스 & 추상 메서드 (1) | 2024.01.02 |
---|---|
[Java] 다형성 (0) | 2024.01.01 |
[Java] static (2) | 2023.12.29 |
[Java] Java 메모리 구조 (1) | 2023.12.29 |
[Java] 제어자, 접근 제어자 (0) | 2023.12.26 |