Ada kata kunci di java - final. Hal ini dapat diterapkan pada kelas, metode, variabel (termasuk argumen metode). Jadi terakhir... - 1Untuk sebuah kelas, ini berarti bahwa kelas tersebut tidak dapat memiliki subkelas, mis. Warisan dilarang. Ini berguna saat membuat immutableobjek (yang tidak dapat diubah), misalnya kelas Stringyang dideklarasikan sebagai final.
public final class String{
}

class SubString extends String{ //Compilation error
}
Perlu diperhatikan juga bahwa pengubah tidak dapat diterapkan pada kelas abstrak (dengan kata kunci abstract), finalkarena ini adalah konsep yang saling eksklusif. Karena suatu metode finalberarti tidak dapat ditimpa di subkelas. Ini berguna ketika kita ingin implementasi aslinya tidak ditimpa.
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Compilation error
        System.out.println("MyReport");
    }
}
Untuk variabel bertipe primitif, ini berarti bahwa setelah ditetapkan, nilainya tidak dapat diubah. Untuk variabel referensi, ini berarti bahwa sekali suatu objek ditetapkan, referensi ke objek tersebut tidak dapat diubah. Itu penting! Tautan tidak dapat diubah, tetapi keadaan objek dapat diubah. Dengan Java 8 konsepnya muncul - effectively final. Ini hanya berlaku untuk variabel (termasuk argumen metode). Intinya adalah meskipun kata kunci tidak ada final, nilai variabel tidak berubah setelah inisialisasi. Dengan kata lain, Anda dapat mengganti kata untuk variabel tersebut finaltanpa kesalahan kompilasi. effectively finalVariabel dapat digunakan di dalam kelas lokal ( Local Inner Classes), kelas anonim ( Anonymous Inner Classes), aliran (Stream API).
public void someMethod(){
    // In the example below, both a and b are effectively final, since the values ​​are set once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final because value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Compilation error
}
Sekarang mari kita melakukan wawancara kecil. Bagaimanapun, tujuan mengikuti kursus JavaRush adalah menjadi pengembang Java dan mendapatkan pekerjaan yang menarik dan bergaji tinggi. Jadi, mari kita mulai.
  1. Apa yang dapat Anda katakan tentang array ketika dideklarasikan final?

  2. Diketahui kelas Stringtersebut immutable, kelas dideklarasikan final, nilai string disimpan dalam array char, yang ditandai dengan kata kunci final.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
Apakah mungkin untuk mengganti nilai suatu objek String(tanpa mengubah referensi ke objek tersebut)? Ini adalah pertanyaan wawancara nyata. Dan seperti yang ditunjukkan oleh latihan, banyak yang menjawabnya dengan salah. Memahami penggunaan kata kunci final, khususnya untuk variabel referensi, sangatlah penting. Selagi Anda berpikir, penyimpangan singkat ke tim JavaRush. Harap tambahkan blok di editor teks Anda yang memungkinkan Anda menyembunyikan konten, dan ketika Anda mengkliknya, tampilkan konten ini. Jawaban:
  1. Karena array adalah sebuah objek, finalartinya setelah memberikan referensi ke suatu objek, array tersebut tidak dapat diubah lagi, tetapi keadaan objek tersebut dapat diubah.

    final int[] array = {1,2,3,4,5};
    array[0] = 9;	//ok, because change the contents of the array - {9,2,3,4,5}
    array = new int[5]; //compile error
  2. Ya kamu bisa. Kuncinya adalah memahami penggunaan kata berduri finaldengan benda. Menggunakan ReflectionAPI untuk menggantikan nilainya.

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 value field in the String class
        Field field = value.getClass().getDeclaredField("value");
        //Let's change it
        field.setAccessible(true);
        //Set new value
        field.set(value, "JavaRush".toCharArray());

        System.out.println(value);

        /* Вывод:
         * Old value
         * JavaRush
         */
    }
}
Harap dicatat bahwa jika kami mencoba mengubah variabel akhir dari tipe primitif dengan cara ini, tidak ada yang berhasil. Saya sarankan Anda meyakinkan diri sendiri tentang hal ini: buat kelas Java, misalnya, dengan final intsebuah bidang dan coba ubah nilainya melalui Reflection API. Semoga sukses untuk semuanya!