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

Java 자바 Set – HashSet, TreeSet, LinkedHashSet 정리

소개 자바에서 Set은 중복을 허용하지 않는 데이터 집합을 의미합니다. List와 달리 동일한 요소를 여러 번…

1개월 ago

Java 자바 Hash 해시 제대로 이해하기

해시(Hash)란 무엇인가? 해시(Hash)는 자바 프로그래밍에서 빠르고 효율적인 데이터 저장 및 검색을 위한 핵심적인 개념입니다. 이…

2개월 ago

Java 자바 리스트 (List) 정리

List란 무엇인가? List는 자바 컬렉션 프레임워크의 핵심 인터페이스 중 하나로, 순서가 있는 데이터를 다루는 데…

2개월 ago

Java 자바 LinkedList 동작 원리와 사용법

LinkedList란 무엇인가? LinkedList는 자바에서 유용하게 사용되는 자료구조 중 하나로, 연결 리스트 방식을 이용하여 데이터를 관리하는…

2개월 ago

Java 자바 ArrayList 동작 원리와 사용법

ArrayList란 무엇인가? ArrayList는 자바에서 가장 널리 사용되는 컬렉션 중 하나로, 가변 크기의 배열을 구현한 클래스입니다.…

2개월 ago

Java 자바 제네릭(Generic) 개념과 문법 알아보기

제네릭(Generic)이란? 자바 제네릭은 코드의 재사용성을 높이고 타입 안전성을 보장하는 중요한 개념입니다. 이 블로그 글에서는 자바…

2개월 ago