Categories: Java

Java 자바 final 과 static final 특징과 사용법

final 이란?

자바에서 final은 변수, 메소드, 클래스 등에 적용되어 특정한 의미와 제약을 부여합니다. final로 선언된 요소는 더 이상 변경할 수 없으며, 여러 컨텍스트에서 사용됩니다.

final 특징

  1. final 변수
    • final로 선언된 변수는 한 번만 초기화되고, 그 이후에는 값을 변경할 수 없습니다.
    • 초기화는 선언 시에 이루어지거나 생성자에서 이루어져야 합니다.
  2. final 메소드
    • final로 선언된 메소드는 하위 클래스에서 오버라이드(재정의)될 수 없습니다. 즉, 해당 메소드의 내용을 변경할 수 없게 됩니다.
  3. final 클래스
    • final로 선언된 클래스는 상속될 수 없습니다. 다른 클래스에서 이 클래스를 확장(상속)할 수 없게 됩니다.
  4. final 참조 변수
    • final로 선언된 변수는 한 번만 초기화되고 그 이후에는 값을 변경할 수 없습니다. 그러나 final 변수가 참조하는 객체의 내부 상태는 변경될 수 있습니다.
    • 예를 들어, final로 선언된 참조 변수가 가리키는 배열 또는 컬렉션의 내부 요소는 변경될 수 있습니다.
    • 이는 final 변수가 값을 가지고 있는 것이 아니라, 주소를 가리키고 있어서 그 주소가 가리키는 객체의 내부 상태에는 영향을 주지 않기 때문입니다

final 사용법

자바에서의 final 키워드는 변수, 메소드, 또는 클래스에 적용될 수 있는 한정자로, 해당 요소에 대한 변경을 허용하지 않음을 나타냅니다.

final 변수

  • final 변수는 선언과 동시에 초기화되어야 합니다. 한 번 초기화된 이후에는 값을 변경할 수 없습니다.
  • 이로써 변수의 값이 프로그램 실행 도중 변경되는 것을 방지하고, 상수로 사용되어 프로그램의 안정성을 향상시킵니다.
Java
final int MAX_VALUE = 100;
Java

final 메소드

  • final 메소드는 하위 클래스에서 오버라이드(재정의)될 수 없습니다. 즉, 부모 클래스에서 정의된 final 메소드의 내용은 하위 클래스에서 변경할 수 없습니다.
  • 이를 통해 특정 메소드가 항상 일정한 동작을 보장하며, 코드의 안정성을 유지할 수 있습니다.
Java
public class Parent {
    final void printMessage() {
        System.out.println("This is a final method.");
    }
}

public class Child extends Parent {
    // 아래의 코드는 오류를 발생시킵니다.
    // void printMessage() { // 오버라이드 시도
    //     System.out.println("Trying to override the final method.");
    // }
}
Java

final 클래스

  • final 클래스는 다른 클래스에서 상속될 수 없습니다. 즉, 해당 클래스를 확장(상속)하는 것이 불가능합니다.
  • 이로써 특정 클래스의 디자인을 변경하지 못하도록 하여 코드의 안정성과 일관성을 유지할 수 있습니다.
Java
final class FinalClass {
    // 클래스 내용
}

// 아래의 코드는 오류를 발생시킵니다.
// class SubClass extends FinalClass { // 상속 시도
//     // 하위 클래스 내용
// }
Java

final 참조 변수

  • final 키워드가 참조형 변수에 적용될 때, 변수 자체는 재할당이 불가능하게 되지만, 참조 대상 안에 있는 객체의 내부 상태(멤버 변수 등)는 변경 가능할 수 있습니다.
💡참조 변수의 재할당 금지
  • final 참조 변수는 한 번 할당된 후에는 다른 객체로 재할당할 수 없습니다.
Java
final MyClass myObject = new MyClass();
// myObject = new MyClass(); // 오류 발생! final 참조 변수는 재할당이 불가능합니다.
Java

💡참조 대상의 내부 상태 변경 가능
  • final 참조 변수가 가리키는 객체의 내부 상태는 변경 가능합니다. 즉, 참조 대상이 가변 객체인 경우, 객체 내부의 상태는 변경될 수 있습니다.
Java
final StringBuilder stringBuilder = new StringBuilder("Hello");
stringBuilder.append(", World!"); // 내부 상태 변경 가능
Java

✔️final 키워드를 사용하면 프로그램의 일관성을 유지하고 버그를 방지하며, 코드의 안정성을 높이는 데 도움이 됩니다.

static final

static final은 자바에서 사용되는 키워드의 조합으로, 클래스 레벨에서 사용되는 상수를 나타냅니다. 이는 해당 필드가 클래스의 인스턴스가 아닌 클래스 자체에 속한다는 것을 의미하며, 값이 한 번 할당되면 변경할 수 없는 상수임을 나타냅니다. 상수명은 모두 대문자로 나타냅니다.

클래스 레벨의 상수

  • static final로 선언된 필드는 해당 클래스의 인스턴스가 아닌 클래스 자체에 속하는 상수로 취급됩니다.
Java
public class Constants {
    public static final double PI = 3.14;
    public static final int MAX_VALUE = 100;
}
Java

한 번 할당된 후 변경 불가

  • static final 필드는 선언과 동시에 초기화되어야 하며, 이후에는 값을 변경할 수 없습니다.
Java
Constants.PI = 3.14159; // 오류 발생! static final 필드는 재할당이 불가능합니다.
Java

인스턴스 생성과 무관

  • 클래스가 인스턴스화되지 않아도 static final 필드에 접근할 수 있습니다. 클래스 로딩 시에 초기화되므로, 인스턴스 생성 여부와 상관없이 사용 가능합니다.

static final의 활용

  • 상수 정의
    • static final은 주로 상수 값을 정의할 때 사용됩니다. 예를 들어, 수학적인 상수나 프로그램 전체에서 공유되는 값들을 선언하는 데 유용합니다.
  • 코드 가독성 향상
    • 클래스 레벨에서 상수를 정의하면, 해당 값들을 한곳에서 관리할 수 있어 코드의 가독성이 향상됩니다.
  • 컴파일러 최적화
    • static final로 선언된 상수는 컴파일 타임에 상수로 취급되어 최적화에 도움이 됩니다.

예시

Java
public class MathConstants {
    public static final double PI = 3.14;
    public static final double E = 2.71828;
    public static final int MAX_ITERATIONS = 1000;
}
Java

✔️위의 예시에서 PI, E, MAX_ITERATIONS는 상수로 사용되며, 다른 클래스에서 해당 클래스를 import하여 사용할 수 있습니다. 상수 값은 변경되지 않고 고정되어 있어야 하므로, static final을 사용하여 정의합니다.

결론

자바에서의 final 키워드는 변수, 메소드, 클래스에 적용되어 다양한 의미를 부여합니다. final로 선언된 변수는 한 번만 초기화되고 그 이후에는 값을 변경할 수 없습니다. 이는 변수가 한 번 초기화되면 그 값을 변경할 수 없도록 고정되어, 상수의 특성을 가지게 됩니다.

메소드에 final을 사용하면 해당 메소드는 하위 클래스에서 오버라이드할 수 없어, 메소드의 구현이 최종적이라는 의미를 전달합니다. 마찬가지로, final로 선언된 클래스는 상속이 불가능하므로, 해당 클래스의 특성이 변하지 않아야 함을 나타냅니다.

또한, final 참조 변수는 한 번만 초기화되고 그 이후에는 값을 변경할 수 없습니다. 그러나 final 변수가 참조하는 객체의 내부 상태는 변경될 수 있습니다. 이는 final 변수가 값을 가지고 있는 것이 아니라 주소를 가리키고 있어서, 그 주소가 가리키는 객체의 내부 상태에는 영향을 주지 않기 때문입니다.

이렇게 final 키워드는 프로그램의 안정성과 일관성을 높이는 데 도움을 주며, 상수, 메소드, 클래스, 참조 변수 등 다양한 요소에 적용되어 사용됩니다.

suover

Recent Posts

그림으로 쉽게 배우는 자료구조와 알고리즘: 미션3 | 문서 압축 (허프만 코딩)

들어가며 소프트웨어가 처리해야 하는 데이터 양이 늘어날수록, 단순히 기능 구현만으로는 성능과 효율을 보장하기 어렵습니다. 특히…

2주 ago

만들면서 쉽게 배우는 컴퓨터 구조: 미션3 | STOREB 명령어와 A·B 비교 구현

들어가며 소프트웨어를 구현할 때 성능 최적화나 안정성을 높이려면, 단순히 고수준 코드만 신경 쓰는 것을 넘어…

2주 ago

그림으로 쉽게 배우는 자료구조와 알고리즘: 미션2 | CPU 스케줄링

들어가며 소프트웨어가 복잡해질수록, 단순히 알고리즘의 시간복잡도만으로는 모든 문제를 해결할 수 없습니다. 특히 운영체제 수준에서는 다중…

3주 ago

만들면서 쉽게 배우는 컴퓨터 구조: 미션2 | 터널 연결부터 32바이트 RAM까지

들어가며 복잡한 소프트웨어가 원활히 동작하려면 단순히 코드만 잘 짜는 것으로는 부족합니다. 트랜잭션 처리나 대규모 데이터…

3주 ago

그림으로 쉽게 배우는 자료구조와 알고리즘: 미션1 | 메모리 검색

들어가며 소프트웨어를 개발할 때 메모리 관리 방식은 프로그램의 안정성과 성능을 좌우하는 핵심 요소입니다. 특히 자바스크립트,…

4주 ago

만들면서 쉽게 배우는 컴퓨터 구조: 미션1 | 진리표부터 회로 구현까지

들어가며 소프트웨어 개발자는 코드가 어떻게 실행되는지 정확히 이해해야 할 필요가 있습니다. 우리가 작성한 프로그램은 결국…

4주 ago