java-da açar söz var - final. O, siniflərə, metodlara, dəyişənlərə (metod arqumentləri daxil olmaqla) tətbiq oluna bilər. Beləliklə, son... - 1Bir sinif üçün bu o deməkdir ki, sinfin alt sinifləri ola bilməz, yəni. Vərəsəlik qadağandır. Bu (dəyişməz) obyektlər yaratarkən faydalıdır immutable, məsələn, Stringkimi elan edilən sinif final.
public final class String{
}

class SubString extends String{ //Compilation error
}
Onu da qeyd etmək lazımdır ki, dəyişdirici abstrakt siniflərə tətbiq edilə bilməz (açar sözü ilə abstract), finalçünki bunlar bir-birini istisna edən anlayışlardır. Metod üçün finalo deməkdir ki, onu alt siniflərdə ləğv etmək olmaz. Bu, orijinal tətbiqin ləğv edilməməsini istədiyimiz zaman faydalıdır.
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Compilation error
        System.out.println("MyReport");
    }
}
Primitiv tipli dəyişənlər üçün bu o deməkdir ki, təyin edildikdən sonra dəyəri dəyişdirilə bilməz. İstinad dəyişənləri üçün bu o deməkdir ki, obyekt təyin edildikdən sonra həmin obyektə istinad dəyişdirilə bilməz. Vacibdir! Bağlantı dəyişdirilə bilməz, lakin obyektin vəziyyəti dəyişdirilə bilər. Java 8 ilə konsepsiya ortaya çıxdı - effectively final. O, yalnız dəyişənlərə (metod arqumentləri daxil olmaqla) aiddir. Məsələ ondadır ki, açar sözünün açıq-aşkar olmamasına baxmayaraq final, başlanğıcdan sonra dəyişənin dəyəri dəyişmir. Başqa sözlə, belə bir dəyişən üçün finalkompilyasiya xətası olmadan bir söz əvəz edə bilərsiniz. Dəyişənlər yerli siniflər ( ), anonim siniflər ( ), axınlar (Stream API) effectively finaldaxilində istifadə edilə bilər .Local Inner ClassesAnonymous Inner Classes
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
}
İndi kiçik bir müsahibə verək. Axı JavaRush kursunu keçməkdə məqsəd Java proqramçısı olmaq və maraqlı və yaxşı maaşlı iş əldə etməkdir. Beləliklə, başlayaq.
  1. Massiv elan edildikdə onun haqqında nə deyə bilərsiniz final?

  2. Məlumdur ki , sinifdir String, immutablesinif elan edilir , sətirin dəyəri açar sözü ilə qeyd olunan finalmassivdə saxlanılır .charfinal

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
StringObyektin dəyərini (obyektə istinadı dəyişmədən) əvəz etmək mümkündürmü ? Bunlar real müsahibə suallarıdır. Təcrübə göstərir ki, çoxları onlara səhv cavab verirlər. Xüsusilə istinad dəyişənləri üçün açar sözünün istifadəsini başa düşmək finalçox vacibdir. Siz düşünərkən JavaRush komandasına qısa bir nəzər salın. Mətn redaktorunuza məzmunu gizlətməyə imkan verən blok əlavə edin və üzərinə kliklədiyiniz zaman bu məzmunu göstərin. Cavablar:
  1. Çünki massiv obyektdir, yəni finalobyektə istinad təyin edildikdən sonra onu artıq dəyişdirmək olmur, lakin obyektin vəziyyəti dəyişdirilə bilər.

    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. Bəli sən bacararsan. finalƏsas odur ki, tikanlı sözün obyektlərlə istifadəsini başa düşməkdir . Dəyəri əvəz etmək üçün ReflectionAPI istifadə edir.

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
         */
    }
}
Nəzərə alın ki, əgər biz primitiv tipin son dəyişənini bu şəkildə dəyişməyə çalışsaq, heç nə alınmayacaq. Özünüzü buna inandırmağı təklif edirəm: məsələn, final intsahə ilə Java sinfi yaradın və Reflection API vasitəsilə onun dəyərini dəyişməyə çalışın. Hamıya uğurlar!