자바에는 final이라는 키워드가 있습니다. 클래스, 메소드, 변수(메소드 매개변수 포함)에 적용할 수 있습니다. 클래스의 경우 final 키워드는 클래스가 하위 클래스를 가질 수 없음을 의미합니다. 즉, 상속이 금지됩니다... 이는 변경 불가능한(변경 불가능한) 객체를 생성할 때 유용합니다. 예를 들어, String 클래스는 final로 선언됩니다.
public final class String {
}

class SubString extends String { // Compilation error
}
또한 최종 수정자는 추상 클래스(키워드 abstract가 있는 클래스)에는 상호 배타적인 개념이기 때문에 적용할 수 없다는 점에 유의해야 합니다. 최종 메서드의 경우 한정자는 해당 메서드를 하위 클래스에서 재정의할 수 없음을 의미합니다. 이는 원래 구현의 변경을 방지하려는 경우에 유용합니다.
public class SuperClass {
    public final void printReport() {
        System.out.println("Report");
    }
}

class SubClass extends SuperClass {
    public void printReport() { //Compilation error
        System.out.println("MyReport");
    }
}
기본 유형의 변수의 경우 final 키워드는 한 번 할당된 값을 변경할 수 없음을 의미합니다. 참조 변수의 경우 개체가 할당된 후에는 해당 개체에 대한 참조를 변경할 수 없음을 의미합니다. 이건 중요하다! 참조는 변경할 수 없지만 개체의 상태는 변경할 수 있습니다. Java 8은 사실상 최종이라는 새로운 개념을 도입했습니다. 변수(메소드 매개변수 포함)에만 적용됩니다. 결론은 final 키워드가 없음에도 불구하고 변수의 값은 초기화 후에 변경되지 않는다는 것입니다. 즉, 컴파일 오류 없이 이러한 변수에 final 키워드를 적용할 수 있습니다. 효과적으로 최종 변수는 로컬 클래스(로컬 내부 클래스), 익명 클래스(익명 내부 클래스) 및 스트림(Stream API) 내에서 사용할 수 있습니다.
public void someMethod() {
    // In the example below, both a and b are effectively final, since they are assigned values only once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final since its value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); // OK
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); // Compilation error
}
자, 잠시 인터뷰를 해보자. 결국 CodeGym 과정을 이수하는 목표는 Java 개발자가 되어 흥미롭고 보수가 좋은 직업을 찾는 것입니다. 자, 시작하겠습니다.
  1. 최종 선언된 배열에 대해 무엇을 말할 수 있습니까?

  2. 우리는 String 클래스가 불변이라는 것을 알고 있습니다. 클래스는 final로 선언됩니다. 문자열 값은 final 키워드로 표시된 char 배열에 저장됩니다.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
객체에 대한 참조를 변경하지 않고 String 객체의 값을 바꿀 수 있습니까? 실제 면접 질문입니다. 그리고 연습에 따르면 많은 후보자가 올바르게 대답하지 않습니다. 특히 참조 변수에 대해 final 키워드가 사용되는 방식을 이해하는 것은 매우 중요합니다. 고민하다가 코드짐팀에 작은 부탁 하나 할게요. 텍스트 편집기를 클릭하면 내용을 표시하거나 숨길 수 있는 블록을 추가할 수 있는 기능을 제공하십시오. 답변:
  1. 배열은 객체이므로 final 키워드는 배열에 대한 참조가 할당되면 참조를 변경할 수 없음을 의미합니다. 즉, 개체의 상태를 변경할 수 있습니다.

    final int[] array = {1, 2, 3, 4, 5};
    array[0] = 9;	 // OK, because we're changing the contents of the array: {9, 2, 3, 4, 5}
    array = new int[5]; // Compilation error
  2. 그래 우리는 할 수있어. 가장 중요한 것은 객체와 함께 사용될 때 까다로운 최종 키워드가 무엇을 의미하는지 이해하는 것입니다. Reflection API를 사용하여 값을 바꿀 수 있습니다.

import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        // Get the String class's value field
        Field field = value.getClass().getDeclaredField("value");
        // Make it mutable
        field.setAccessible(true);
        // Set a new value
        field.set(value, "CodeGym".toCharArray());

        System.out.println(value);

        /* Output:
         * Old value
         * CodeGym
         */
    }
}
이런 식으로 기본 유형의 최종 변수를 변경하려고 시도했다면 아무 일도 일어나지 않았을 것입니다. 예를 들어 최종 int 필드가 있는 Java 클래스를 만들고 Reflection API를 사용하여 해당 값을 변경해 보십시오. 모두에게 행운을 빕니다!