[Java Final] 키워드 파헤치기개발노트/Java2024. 5. 9. 13:05
Table of Contents
개념
final은 변수, 메서드, 클래스의 값을 변경할 수 없게 만든다.
한마디로 낙장불입!
적절한 위치에 final을 사용하여 코드 작성 의도를 명확히 하고, 의도하지 않은 변화로부터 코드를 보호하는데 도움을 준다.
변수, 메서드, 클래스 중 어떤 곳에 사용하느냐에 따라 바꿀 수 없는 제약사항이 다르게 적용되기 때문에, 아래 내용을 통해 한번 자세히 알아보자!
변수(variable)에서 final
지역변수(local)
public static void main(String[] args) {
// 지역변수
final String superpil = "hello";
superpil = "world"; // 컴파일 에러
}
- superpil 변수를 선언하는 동시에 “hello”를 초기화했다.
- 다음 "world"를 재할당하면 컴파일 에러가 발생!
- 이유는 final 변수에 최초 한 번 값이 할당된 후 값을 변경했기 때문!
public static void main(String[] args) {
// 지역변수
final String superpil;
superpil = "hello"; // 가능!
superpil = "world"; // 컴파일 에러
}
- 이번에는 superpil변수를 선언만 하고 초기화를 하지 않았다.
- 이후 “hello”를 할당했다. 이건 정상 할당된다.
- 이후 “world”를 재할당한다. 이건 컴파일 에러가 발생!
- 여기서 중요한 것은 final은 최초로 초기화된 값을 변경하려 할 때만 에러가 발생한다는 점!
매개변수(parameter)
public static void main(String[] args) {
demo("superpil");
}
public static void demo(final String param) {
param = "hello"; // 컴파일 에러
System.out.println(param);
}
- 매개변수에도 final을 사용할 수 있다.
- 매개변수로 받은 값을 변경 시 컴파일 에러 발생!
- 매개변수 값을 메서드 내부에서 변경하지 못하도록 제한하고 싶을 때 사용하는 것이 좋다.
인스턴스 변수(instance)
public class Superpil {
final int value = 20;
}
public static void main(String[] args) {
Superpil superpil = new Superpil();
System.out.println(superpil.value); // 20
superpil.value = 50; // 컴파일 에러
}
- Superpil클래스에 20으로 초기화된 value 변수가 있다.
- Superpil클래스를 인스턴스로 생성하는 동시에 value는 20으로 설정된다.
- 출력해 보면 당연히 20이 출력된다.
- value값을 변경하게 되면 컴파일 에러 발생!
- value에 final를 사용해 변경불가능하게 만들었기 때문!
// Superpil class
public class Superpil {
final int value; // 컴파일 에러
}
// Main class
public static void main(String[] args) {
Superpil superpil = new Superpil();
superpil.value = 50;
}
- 이번에는 final을 사용하고 바로 초기화하지 않아 보자.
- 이전 지역변수 예제는 선언과 초기화를 분리해도 가능했다.
- 인스턴스 변수도 지역변수처럼 가능할까? 정답은 No!
// Superpil class
public class Superpil {
final int value1;
final int value2;
final int vlaue3 = 50;
public Superpil(int value2){
this.value1 = 20;
this.value2 = value2;
}
}
// Main class
public static void main(String[] args) {
Superpil superpil = new Superpil(30);
System.out.println(superpil.value1); // 20
System.out.println(superpil.value2); // 30
System.out.println(superpil.value3); // 50
}
- final을 사용한 인스턴스 변수가 있다면 인스턴스가 초기화되는 시점에 변수는 반드시 초기화되어야 한다.
- Superpil 클래스가 인스턴스로 생성될 때 value1, value2, value3은 생성자에 의해 초기화가 된다.
- 당연히 value1, value2, value3의 값은 변경 불가능하다.
참조형
// superpil 클래스
public class Superpil {
int value;
}
// main 클래스
public static void main(String[] args) {
final Superpil superpil = new Superpil();
superpil.value = 20;
System.out.println(superpil.value); // 20
superpil = new Superpil(); // 컴파일 에러
}
- 이번에는 인스턴스 변수에 final을 사용하지 않고 superpil변수에 사용해 보자.
- value값은 변경 가능하다. 하지만 superpi변수에 초기화된 값을 변경할 경우 에러가 발생한다.
- superpil 변수는 new Superpil 인스턴스의 참조값을 할당받았다.
- 여기서 참조값이란, new Superpil의 (힙) 메모리 주소값이다.
- 즉, 메모리 주소값이 할당된 것이고, value가 할당된 것이 아니기 때문에 값(value)은 변경 가능하다. (메모리 주소값으로 value를 찾아서 변경할 수 있다.)
- 다만, final을 사용한 superpil 변수에 다른 값을 할당할 경우 참조값(메모리 주소값)이 변경되기 때문에 superpil변수는 변경 불가능하다.
메서드(method)에서 final
// 부모 클래스
public class Parent {
public final void printMethod() {
System.out.println("Parent");
}
}
// 자식 클래스
public class Child extends Parent {
// 컴파일 에러
@Override
public void printMethod() {}
}
- 상속관계에서 일반적으로 자식은 부모의 메서드를 오버라이딩 할 수 있다.
- 다만, 부모 메서드에 final을 사용하면 자식은 해당 메서드를 오버라이딩할 수 없다.
- 부모 클래스에서 정의한 메서드를 변경하지 못하고 강제성을 의도하고 싶을 때 사용하면 좋다.
클래스(class)에서 final
// 부모 클래스
public final class Parent {}
// 자식 클래스
// 컴파일 에러
public class Child extends Parent {}
- 메서드와 동일하게 final이 붙은 클래스는 다른 클래스가 상속 불가능하다.
정리
지금까지 작성된 내용을 요약해 보자.
- 지역변수: 한 번 초기화된 final 지역변수는 재할당할 수 없다.
- 매개변수: final 매개변수는 메서드 내에서 변경할 수 없어 값의 불변성을 보장한다.
- 인스턴스 변수: final 인스턴스 변수는 생성자에서 초기화되어야 하며, 초기화 이후에는 수정할 수 없다.
- 참조형 변수: 객체 참조 자체는 변경할 수 없으나, 객체 내부의 속성은 수정 가능하다.
- 메서드: final 메서드는 하위 클래스(자식)에서 오버라이드할 수 없다.
- 클래스: final 클래스는 상속될 수 없어, 클래스의 확장을 막는다.
주니어개발자의 성장기였습니다.
댓글로 부족한 내용이나 공유하고 싶은 의견을 채워주세요! 우리 함께 성장해요!😄
'개발노트 > Java' 카테고리의 다른 글
[Java Wrapper Class] 래퍼 클래스 파헤치기 (1) | 2024.06.13 |
---|---|
[Java Immutable Object] 불변 객체 파헤치기 (0) | 2024.05.20 |
[Java Basic] 자바 표준 라이브러리 소개 (0) | 2024.05.14 |
[Java 초급] Overloading - 오버로딩 (0) | 2020.08.25 |
@superpil :: 주니어 개발자의 성장기
개발 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!