본문 바로가기
JAVA

Final

by 융디's 2024. 4. 25.
728x90
Final

Final

@2024.04.11

Final 클래스

💡
final 키워드가 붙은 클래스로 해당 클래스는 최종적이며 변경할 수 없기에, 다른 클래스의 상속받을 수 없게 하는 클래스다. (넌 부모가 될 수 없어!)
  • 사용 용도
    • 불변성 보장
      • 클래스 시 생성 시 그 상태가 변경되지 않도록 함으로써, 안정성과 보안을 향상
    • 상속 방지
      • 특정 클래스의 기능이나 로직이 변경되지 않도록 유지하고 싶을 때 사용
    • 불변 클래스 생성
      • 불변 객체를 만드는 데 유용하며, 이 객체는 생성 후 그 상태가 변경되지 않으므로, 여러 면에서 프로그램의 신뢰성을 높일 수 있다.
    • 성능 최적화
      • 컴파일러와 JVM은 final 클래스에 대해 성능 최적화를 수행 시킬 수 있다.
      • fianl 클래스의 메서드는 오버라이딩 되지 않기 대문에, 컴파일 시 메서드 호출이 결정될 수 있어, 실행 시간이 단축될 수 있다.
  • 특징
    • 확장 불가능
      • 다른 클래스는 final 클래스를 상속받을 수 없다.
      • 즉 final 클래스의 모든 메서드는 상속되거나 오버라이딩 될 수 없다.
    • 메서드 오버라이딩 방지
      • final 클래스는 상속될 수 없으므로 하위 클래스를 만들 수 없다.

      → final 클래스의 메서드는 하위 클래스에서 오버라이딩을 할 수 없다.

      • 따라서 final 클래스의 모든 메서드는 사실상 final로 간주
final class FinalClass {
    // 이 클래스는 final이기 때문에 상속 불가능 

    private final int value;

    public FinalClass(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

public class Main {
    public static void main(String[] args) {
        FinalClass finalObj = new FinalClass(10);
        System.out.println("Value: " + finalObj.getValue());
    }
}

java.lang.String

💡
문자열을 표현하는 데 사용되는 이 클래스는 불변성을 유지하므로, 한번 생성된 String 객체의 내용은 변경될 수 없다.
  • 이는 String 클래스가 final로 선언되어 있기 때문에, 다른 클래스가 이를 상속받아 변경하는 것이 불가능

java.lang.Math

💡
다양한 수학적 연산과 함수를 제공하는 유틸리티 클래스

java.lang.System

💡
시스템 관련 기능을 제공
  • 주로 시스템의 입력, 출력 및 오류 출력을 관리하는 정적 메서드를 포함하고 있다.

Final 필드

💡
한번 초기화시 그 값을 변경할 수 없는 필드상수를 정의하거나, 객체의 불변성을 보장하는 데 사용한다.
  • 사용 용도
    • 상수 정의
      • 변경되지 않는 고정된 값을 가진 상수를 정의
    • 불변 객체 생성
      • 객체의 불변성을 보장하려면, 객체가 생성된 후에 그 상태가 변경되지 않아야 한다.
      • final 필드를 사용하면 객체의 핵심 속성이 한번 설정된 후에는 변경되지 않는다.
      • 객체의 예측 가능성과 신뢰성을 높인다.
    • 스레드 안정성
      • 멀티 스레딩 환경에서 final 필드는 스레드 간의 안전한 읽기 작업을 보장한다.
      • 한번 초기화된 값은 변경되지 않기 때문에, 스레드 간에 동기화 없이 안전하게 읽을 수 있다.
    • 메모리 가시성 보장
      • 객체가 생성될 때 한 번만 쓰이고, 이후에는 변경되지 않기 때문에 JVM은 메모리 가시성을 보장
      • 모든 스레드에게 일관되게 보인다.
  • 특성
    • 초기화 제한
      • 선언할 때나 생성자에서만 초기화 가능
    • 객체의 핵심 속성 보호
      • 객체가 특정한 상태를 유지해야 할 때 final 필드로 선언함으로써 해당 값의 무결성을 유지
public class FinalFieldExample {
    private final int constantValue; // final 필드 선언

    public FinalFieldExample(int value) {
        this.constantValue = value; // final 필드 초기화 
    }

    public int getConstantValue() {
        return constantValue;
    }

    public static void main(String[] args) {
        FinalFieldExample obj = new FinalFieldExample(10);
        System.out.println("Initial constant value: " + obj.getConstantValue());
        obj.constantValue = 20; // final 필드에 재할당 하므로 컴파일 에러
    }
}

Final 메서드

💡
한번 선언되면 하위 클래스에서 오버라이딩(재정의) 할 수 없다.
  • 사용 용도
    • 메서드 무결성 보장
      • 특정 메서드의 기능이 그대로 유지되어야 할 때 사용
      • 클래스의 기본 동작을 정의하는 핵심 메서드에 자주 사용
    • 오버라이딩 방지
      • 부모 클래스의 중요한 메서드가 자식 클래스에서 예기치 않게 변경되는 것을 방지
      • 클래스의 동작을 일관되게 유지
    • 보안 강화
      • 외부에서 해당 메서드를 변경하거나 악용하는 것을 방지할 수 있다.
      • 프로그램의 보안 향상
    • 예측 가능한 동작
      • fianl 메서드가 항상 동일한 방식으로 동작한다는 것을 알고 있으므로, 의도치 않은 오류나 버그를 줄 일 수 있다.
  • 특성
    • 재정의 불가능
      • 상속받은 클래스에서 다시 정의할 수 없다.
      • 이는 메서드의 원래 기능과 동작이 보존됨을 의미
    • 클래스의 동작 보호
      • 특정 클래스의 핵심적인 동작이나 로직은 상속받은 클래스에서 변경되지 않는다.
public class Parent {
    // final 메소드
    public final void finalMethod() {
        System.out.println("나는 정적 메서드다.");
    }
}

public class Child extends Parent {
    // final 메소드를 오버라이드하려고 시도하면 컴파일 에러가 발생
     @Override
     public void finalMethod() {
       System.out.println("정적 메서드는 오버라이드 불가능");
     }

    public void nonFinalMethod() {
        System.out.println("나는 일반 메서드다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.finalMethod(); // 부모 클래스의 final 메소드 호출
        child.nonFinalMethod(); // 자식 클래스의 일반 메소드 호출
    }
}

728x90

'JAVA' 카테고리의 다른 글

자동 리소드 닫기  (0) 2024.04.25
예외 처리  (1) 2024.04.25
인터페이스  (0) 2024.04.25
추상 클래스  (0) 2024.04.25
불변 클래스  (0) 2024.04.22