JavaRush /Java Blogu /Random-AZ /Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları. 1-c...
Roman Beekeeper
Səviyyə

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları. 1-ci hissə

Qrupda dərc edilmişdir
Hər kəsə salam, xanımlar və cənablar Proqram Mühəndisləri! Gəlin müsahibə sualları haqqında danışaq. Nəyə hazırlaşmalı olduğunuz və nəyi bilməli olduğunuz haqqında. Bu, bu məqamları təkrarlamaq və ya sıfırdan öyrənmək üçün əla səbəbdir. Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-1 hissəOOP, Java Sintaksisi, Java-dakı istisnalar, kolleksiyalar və çox iş parçacığı haqqında tez-tez verilən sualların kifayət qədər geniş kolleksiyası var, onları rahatlıq üçün bir neçə hissəyə ayıracağam. Əhəmiyyətli:biz yalnız 8-ə qədər Java versiyalarından danışacağıq. 9, 10, 11, 12, 13-dən olan bütün yeniliklər burada nəzərə alınmayacaq. Cavabları yaxşılaşdırmaq üçün hər hansı fikir/şərh qəbul olunur . Xoş oxu, gedək!

Java müsahibəsi: OOP sualları

1. Java hansı xüsusiyyətlərə malikdir?

Cavab:
  1. OOP anlayışları:

    1. obyekt oriyentasiyası;
    2. miras;
    3. kapsulyasiya;
    4. polimorfizm;
    5. abstraksiya.
  2. Çarpaz platforma: Java proqramı heç bir dəyişiklik etmədən istənilən platformada işlədilə bilər. Sizə lazım olan yeganə şey quraşdırılmış JVM-dir (java virtual maşın).

  3. Yüksək performans: JIT (Just In Time compiler) yüksək performansa imkan verir. JIT bayt kodunu maşın koduna çevirir və sonra JVM icraya başlayır.

  4. Multithreading: kimi tanınan icra xətti Thread. JVM adlı bir mövzu yaradır main thread. Proqramçı Thread sinfindən miras alaraq və ya interfeys tətbiq etməklə çoxlu mövzu yarada bilər Runnable.

2. Vərəsəlik nədir?

Vərəsəlik o deməkdir ki, bir sinif digər sinfi miras ala bilər (“ genişləyir ”). Bu yolla siz miras aldığınız sinifdən kodu təkrar istifadə edə bilərsiniz. Mövcud sinif kimi tanınır superclassvə yaradılan sinif kimi tanınır subclass. Onlar da deyirlər parentchild.
public class Animal {
   private int age;
}

public class Dog extends Animal {

}
haradadır və - . Animal_parentDogchild

3. İnkapsulyasiya nədir?

Bu sual tez-tez Java tərtibatçıları ilə müsahibələr zamanı ortaya çıxır. Encapsulation, giriş modifikatorlarından, alıcılar və tənzimləyicilərdən istifadə edərək həyata keçirilməsini gizlədir. Bu, tərtibatçıların zəruri hesab etdiyi yerlərdə xarici istifadə üçün girişi bağlamaq üçün edilir. Həyatdan əlçatan bir nümunə avtomobildir. Mühərrikin işinə birbaşa çıxışımız yoxdur. Bizim üçün iş açarı alışdırmaq və mühərriki işə salmaqdır. Başlıq altında hansı proseslərin baş verəcəyi isə bizim işimiz deyil. Üstəlik, bizim bu fəaliyyətə müdaxiləmiz gözlənilməz vəziyyətə gətirib çıxara bilər ki, bunun da nəticəsində maşını sındırıb özümüzə zərər verə bilərik. Eyni şey proqramlaşdırmada da olur. Vikipediyada yaxşı təsvir edilmişdir . JavaRush -da inkapsulyasiya haqqında məqalə də var .

4. Polimorfizm nədir?

Polimorfizm , proqramın həmin obyektin konkret növü haqqında məlumat olmadan eyni interfeysə malik obyektlərdən eyni şəkildə istifadə etmək qabiliyyətidir. Necə deyərlər, bir interfeys - bir çox tətbiq. Polimorfizmlə siz ümumi davranışlarına əsasən müxtəlif növ obyektləri birləşdirə və istifadə edə bilərsiniz. Məsələn, bizdə iki nəsli olan Animal sinfi var - İt və Pişik. Ümumi Animal sinifinin hamı üçün ümumi davranışı var - səs çıxarın. Heyvanlar sinfinin bütün nəsillərini bir araya toplamalı və “səs çıxarma” metodunu yerinə yetirməli olduğumuz halda, polimorfizm imkanlarından istifadə edirik. Bu belə görünəcək:
List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Beləliklə, polimorfizm bizə kömək edir. Üstəlik, bu, polimorfik (həddindən artıq yüklənmiş) üsullara da aiddir. Polimorfizmdən istifadə təcrübəsi

Müsahibə Sualları - Java Sintaksisi

5. Java-da konstruktor nədir?

Aşağıdakı xüsusiyyətlər etibarlıdır:
  1. Yeni obyekt yaradıldıqda proqram bunun üçün müvafiq konstruktordan istifadə edir.
  2. Konstruktor bir metod kimidir. Onun özəlliyi ondan ibarətdir ki, heç bir geri dönən element yoxdur (boş daxil olmaqla) və onun adı sinfin adı ilə eynidir.
  3. Heç bir konstruktor açıq şəkildə yazılmayıbsa, avtomatik olaraq boş konstruktor yaradılacaq.
  4. Konstruktoru ləğv etmək olar.
  5. Parametrləri olan konstruktor yaradılıbsa, lakin sizə parametrsiz də lazımdırsa, avtomatik olaraq yaradılmadığı üçün onu ayrıca yazmalısınız.

6. Hansı iki sinif Obyektdən miras qalmır?

Təxribatlara aldanmayın, belə siniflər yoxdur: bütün siniflər birbaşa və ya əcdadlar vasitəsilə Obyekt sinfindən miras qalıb!

7. Yerli Dəyişən nədir?

Java developer müsahibəsi zamanı başqa bir məşhur sual. Yerli dəyişən metod daxilində müəyyən edilmiş və metod icra olunana qədər mövcud olan dəyişəndir. İcra başa çatdıqdan sonra yerli dəyişən mövcud olmağı dayandıracaq. Budur, main() metodunda helloMessage yerli dəyişənini istifadə edən proqram:
public static void main(String[] args) {
   String helloMessage;
   helloMessage = "Hello, World!";
   System.out.println(helloMessage);
}

8. Nümunə Dəyişən nədir?

Nümunə Dəyişən bir sinif daxilində müəyyən edilmiş dəyişəndir və obyektin mövcud olduğu ana qədər mövcuddur. Nümunə olaraq iki dəyişən nectarCapacity və maxNectarCapacity olan Bee sinfini göstərmək olar:
public class Bee {

   /**
    * Current nectar capacity
    */
   private double nectarCapacity;

   /**
    * Maximal nectar that can take bee.
    */
   private double maxNectarCapacity = 20.0;

  ...
}

9. Giriş modifikatorları hansılardır?

Giriş modifikatorları siniflərə, metodlara və dəyişənlərə girişi fərdiləşdirməyə imkan verən bir vasitədir. Girişi artırmaq üçün sifariş edilən aşağıdakı dəyişdiricilər var:
  1. private- metodlar, sahələr və konstruktorlar üçün istifadə olunur. Giriş səviyyəsi yalnız elan edildiyi sinifdir.
  2. package-private(default)- dərslər üçün istifadə edilə bilər. Yalnız sinfin, metodun, dəyişənin, konstruktorun elan olunduğu xüsusi paketdə giriş.
  3. protectedpackage-private— dəyişdiricisi olan sinifdən miras qalan siniflər üçün + ilə eyni giriş protected.
  4. public- dərslər üçün də istifadə olunur. Bütün proqrama tam giriş.
  5. Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-2 hissə

10. Üstünlük verən üsullar nədir?

Metodun üstünlüyü uşaq valideyn sinifinin davranışını dəyişdirmək istədikdə baş verir. Əgər siz ana metodda olanların icra olunmasını istəyirsinizsə, uşaqda super.methodName() kimi konstruksiyadan istifadə edə bilərsiniz, bu ana metodun işini görəcək və yalnız bundan sonra məntiq əlavə edə bilərsiniz. Qarşılanmalı olan tələblər:
  • metodun imzası eyni olmalıdır;
  • qaytarılması dəyəri eyni olmalıdır.

11. Metod imzası nədir?

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-3 hissəMetod imzası metodun adı və metodun qəbul etdiyi arqumentlər toplusudur. Metod imzası, metodların həddindən artıq yüklənməsi zamanı metod üçün unikal identifikatordur.

12. Metodun həddən artıq yüklənməsi nədir?

Metodun həddən artıq yüklənməsi polimorfizmin bir xüsusiyyətidir, burada metod imzasını dəyişdirərək eyni hərəkətlər üçün müxtəlif üsullar yarada bilərsiniz:
  • eyni metodun adı;
  • müxtəlif arqumentlər;
  • fərqli qaytarma növü ola bilər.
Məsələn, eynisi add()aşağıdakı ArrayListkimi yüklənə bilər və daxil olan arqumentlərdən asılı olaraq əlavəni fərqli şəkildə yerinə yetirəcək:
  • add(Object o)- sadəcə bir obyekt əlavə edir;
  • add(int index, Object o)— obyekti konkret indeksə əlavə edir;
  • add(Collection<Object> c)— obyektlərin siyahısını əlavə edir;
  • add(int index, Collection<Object> c)— müəyyən indeksdən başlayaraq obyektlərin siyahısını əlavə edir.

13. İnterfeys nədir?

Java-da çoxlu varislik həyata keçirilmir, ona görə də bu problemi aradan qaldırmaq üçün bildiyimiz interfeyslər əlavə edildi ;) Uzun müddətdir ki, interfeyslərdə yalnız onları həyata keçirmədən metodlar var idi. Bu cavabın bir hissəsi olaraq onlar haqqında danışacağıq. Misal üçün:

public interface Animal {
   void makeSound();
   void eat();
   void sleep();
}
Bəzi nüanslar bundan irəli gəlir:
  • interfeysdəki bütün üsullar açıq və mücərrəddir;
  • bütün dəyişənlər açıq statik yekundur;
  • siniflər onları miras almır (uzatır), lakin həyata keçirir (həyata keçirir). Üstəlik, istədiyiniz qədər çox interfeys tətbiq edə bilərsiniz.
  • interfeysi həyata keçirən siniflər interfeysin malik olduğu bütün metodların tətbiqini təmin etməlidir.
Bunun kimi:
public class Cat implements Animal {
   public void makeSound() {
       // method implementation
   }

   public void eat() {
       // implementation
   }

   public void sleep() {
       // implementation
   }
}

14. İnterfeysdə standart metod nədir?

İndi standart üsullar haqqında danışaq. Nə üçün, kimin üçün? Bu üsullar hər şeyi “həm sizin, həm də bizim” etmək üçün əlavə edildi. Mən nədən danışıram? Bəli, bir tərəfdən, yeni funksionallıq əlavə etmək lazım idi: lambdalar, Stream API, digər tərəfdən, Java-nın məşhur olduğunu - geriyə uyğunluğu tərk etmək lazım idi. Bunun üçün interfeyslərə hazır həllər təqdim etmək lazım idi. Defolt üsullar bizə belə gəldi. Yəni, standart metod, açar sözü olan interfeysdə həyata keçirilən metoddur default. Məsələn , stream(). CollectionYoxlayın, bu interfeys göründüyü qədər sadə deyil ;). Və ya eyni dərəcədə tanınmış bir forEach()üsul Iterable. Defolt üsullar əlavə olunana qədər də mövcud deyildi. Yeri gəlmişkən, bu barədə JavaRush -da da oxuya bilərsiniz .

15. Bəs iki eyni standart metodu necə miras almaq olar?

Defolt metodun nə olduğuna dair əvvəlki cavaba əsasən, başqa sual verə bilərsiniz. Əgər siz interfeyslərdə metodları tətbiq edə bilirsinizsə, o zaman nəzəri olaraq eyni metodla iki interfeys həyata keçirə bilərsiniz və bunu necə etmək olar? Eyni üsulla iki fərqli interfeys var:
interface A {
   default void foo() {
       System.out.println("Foo A");
   }
}

interface B {
   default void foo() {
       System.out.println("Foo B");
   }
}
Və bu iki interfeysi həyata keçirən bir sinif var. foo()Qeyri-müəyyənliyin qarşısını almaq və kodu tərtib etmək üçün biz sinifdəki metodu ləğv etməliyik Cvə biz sadəcə foo()onun içindəki hər hansı bir interfeysin metodunu çağıra bilərik - Avə ya B. Ancaq konkret interfeys metodunu necə seçmək olar Аvə ya В? Bunun üçün belə bir quruluş var A.super.foo():
public class C implements A, B {
   @Override
   public void foo() {
       A.super.foo();
   }
}
və ya:
public class C implements A, B {
   @Override
   public void foo() {
       B.super.foo();
   }
}
Beləliklə, bir foo()sinif metodu ya interfeysdəki Cstandart metoddan , ya da interfeysdən bir metoddan istifadə edəcəkdir . foo()Afoo()B

16. Abstrakt metodlar və siniflər hansılardır?

abstractJava-da mücərrəd sinifləri və metodları ifadə etmək üçün istifadə olunan qorunan bir söz var . Birincisi, bəzi təriflər. abstractMücərrəd metod mücərrəd sinifdə açar sözlə icra edilmədən yaradılan metoddur . Yəni, bu, interfeysdəki kimi bir üsuldur, yalnız açar söz əlavə etməklə, məsələn:
public abstract void foo();
abstractMücərrəd sinif həm də sözü olan sinifdir :
public abstract class A {

}
Abstrakt sinif bir neçə xüsusiyyətə malikdir:
  • onun əsasında obyekt yaradıla bilməz;
  • onun mücərrəd üsulları ola bilər;
  • onun mücərrəd üsulları olmaya bilər.
Mücərrəd siniflər real həyatda olmayan bir növ abstraksiyanı (tavtologiya üçün üzr istəyirik) ümumiləşdirmək üçün lazımdır, lakin o, çoxlu ümumi davranışları və halları (yəni metodlar və dəyişənlər) ehtiva edir. Həyatdan misallar kifayət qədər çoxdur. Hər şey ətrafımızdadır. Bu, "heyvan", "avtomobil", "həndəsi fiqur" və s. ola bilər.

17. String, String Builder və String Buffer arasındakı fərq nədir?

Dəyərlər Stringsabit simli hovuzda saxlanılır. Bir sıra yaradıldıqdan sonra bu hovuzda görünəcək. Və onu silmək mümkün olmayacaq. Misal üçün:
String name = "book";
...dəyişən sətir hovuzuna istinad edəcək Sabit sətir hovuzu Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-4 hissə Dəyişən adını fərqli qiymətə təyin etsəniz, aşağıdakıları əldə edəcəksiniz:
name = "pen";
Daimi simli hovuz Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-5 hissəBeləliklə, bu iki dəyər orada qalacaq. Simli Bufer:
  • dəyərlər Stringyığında saxlanılır. Dəyər dəyişdirilərsə, yeni dəyər köhnəsi ilə əvəz olunacaq;
  • String Buffersinxronlaşdırılmış və buna görə də ip təhlükəsizdir;
  • İplərin təhlükəsizliyi sayəsində əməliyyat sürəti arzuolunan dərəcədə çox şey yaradır.
Misal:
StringBuffer name = "book";
Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-6 hissəAdın dəyəri dəyişən kimi, yığındakı dəyər də dəyişir: Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-7 hissəStringBuilder ilə tam olaraq eynidir StringBuffer, yalnız iplik təhlükəsiz deyil. Buna görə də onun sürəti ilə müqayisədə aydın şəkildə yüksəkdir StringBuffer.

18. Abstrakt siniflə interfeys arasındakı fərq nədir?

Abstrakt sinif:
  • abstrakt siniflərin standart konstruktoru var; hər dəfə bu mücərrəd sinfin uşağı yaradılanda çağırılır;
  • həm abstrakt, həm də mücərrəd olmayan metodları ehtiva edir. Ümumiyyətlə, o, abstrakt metodları ehtiva etməyə bilər, lakin yenə də mücərrəd sinif ola bilər;
  • mücərrəddən miras qalan sinif yalnız abstrakt metodları həyata keçirməlidir;
  • mücərrəd sinif Nümunə Dəyişənindən ibarət ola bilər (5-ci suala bax).
İnterfeys:
  • konstruktoru yoxdur və işə salına bilməz;
  • yalnız mücərrəd üsullar əlavə edilməlidir (standart metodlar nəzərə alınmır);
  • interfeysi həyata keçirən siniflər bütün metodları həyata keçirməlidir (standart metodlar nəzərə alınmadan);
  • interfeyslər yalnız sabitləri ehtiva edə bilər.

19. Nə üçün massivdə elementə daxil olmaq O(1) alır?

Bu sual sözün əsl mənasında sonuncu müsahibədəndir. Sonradan öyrəndiyim kimi, bu sual insanın necə düşündüyünü görmək üçün verilir. Aydındır ki, bu bilikdə praktiki məna azdır: bu faktı bilmək kifayətdir. Əvvəlcə aydınlaşdırmalıyıq ki, O(1) əməliyyat sabit zamanda baş verdikdə alqoritmin zaman mürəkkəbliyi üçün təyinatdır. Yəni bu təyinat ən sürətli icradır. Bu suala cavab vermək üçün massivlər haqqında nə bildiyimizi başa düşməliyik? Massiv yaratmaq üçün intaşağıdakıları yazmalıyıq:
int[] intArray = new int[100];
Bu qeyddən bir neçə nəticə çıxarmaq olar:
  1. Massiv yaradarkən onun tipi məlum olur.Əgər növü məlumdursa, o zaman massivin hər bir xanasının hansı ölçüdə olacağı aydın olur.
  2. Massivin hansı ölçüdə olacağı məlumdur.
Buradan belə çıxır: hansı xanaya yazılacağını anlamaq üçün sadəcə hansı yaddaş sahəsinə yazılacağını hesablamaq lazımdır. Bir avtomobil üçün bu daha asan ola bilməzdi. Maşın ayrılmış yaddaşın başlanğıcına, bir sıra elementlərə və tək hüceyrə ölçüsünə malikdir. Buradan aydın olur ki, qeyd sahəsi massivin başlanğıc yeri + xananın ölçüsü ilə onun ölçüsünə vurulan yerə bərabər olacaqdır.

ArrayList-də obyektlərə daxil olmaqda O(1)-ni necə əldə edirsiniz?

Bu sual dərhal əvvəlki sualdan sonra gəlir. Düzdür, biz massivlə işlədikdə və orada primitivlər olduqda, bu növün yaradıldığı zaman ölçüsünün nə olduğunu əvvəlcədən bilirik. Bəs şəkildəki kimi bir sxem varsa necə: Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  1-8 hissəvə biz A tipli elementlərlə kolleksiya yaratmaq və müxtəlif tətbiqlər əlavə etmək istəyirik - B, C, D:
List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
Bu vəziyyətdə, hər bir hüceyrənin hansı ölçüdə olacağını necə başa düşmək olar, çünki hər bir obyekt fərqli olacaq və müxtəlif əlavə sahələrə malik ola bilər (və ya tamamilə fərqli ola bilər). Nə etməli? Burada sual elə qoyulur ki, çaşdırsın və çaşsın. Bilirik ki, əslində kolleksiya obyektləri saxlamır, yalnız bu obyektlərə keçidlər verir. Və bütün keçidlərin ölçüsü eynidir və məlumdur. Beləliklə, burada boşluqların sayılması əvvəlki sualdakı kimi işləyir.

21. Avtoboksinq və qutudan çıxarılması

Tarixi məlumat: autoboxing və autounboxing JDK 5-in əsas yeniliklərindən biridir. Autoboxing primitiv tipdən müvafiq sarğı sinifinə avtomatik çevrilmə prosesidir. Avtomatik qutudan çıxarma - avtomatik boksun tam əksini edir - sarğı sinifini primitivə çevirir. Amma qablaşdırma dəyəri varsa null, paketin açılması zamanı bir istisna atılacaq NullPointerException.

Uyğun primitiv - sarğı

Primitiv Sinif sarğısı
boolean Boolean
int Tam
bayt bayt
char Xarakter
sal Sal
uzun Uzun
qısa Qısa
ikiqat İkiqat

Avtomatik qablaşdırma baş verir:

  • sarğı sinfinə primitiv istinad təyin edərkən:

    Java 5-dən ƏVVƏL:

    //manual packaging or how it was BEFORE Java 5.
    public void boxingBeforeJava5() {
       Boolean booleanBox = new Boolean(true);
       Integer intBox = new Integer(3);
       // and so on to other types
    }
    
    после Java 5:
    //automatic packaging or how it became in Java 5.
    public void boxingJava5() {
       Boolean booleanBox = true;
       Integer intBox = 3;
       // and so on to other types
    }
  • ibtidai sarğı gözləyən metoda arqument kimi ötürərkən:

    public void exampleOfAutoboxing() {
       long age = 3;
       setAge(age);
    }
    
    public void setAge(Long age) {
       this.age = age;
    }

Avtomatik qablaşdırma baş verir:

  • sarğı sinfinə primitiv dəyişən təyin etdikdə:

    //before Java 5:
    int intValue = new Integer(4).intValue();
    double doubleValue = new Double(2.3).doubleValue();
    char c = new Character((char) 3).charValue();
    boolean b = Boolean.TRUE.booleanValue();
    
    //and after JDK 5:
    int intValue = new Integer(4);
    double doubleValue = new Double(2.3);
    char c = new Character((char) 3);
    boolean b = Boolean.TRUE;
  • Arifmetik əməliyyatların olduğu hallarda. Onlar yalnız primitiv növlərə aiddir, bunun üçün primitivin qutusunu çıxarmaq lazımdır.

    // Before Java 5
    Integer integerBox1 = new Integer(1);
    Integer integerBox2 = new Integer(2);
    
    // for comparison it was necessary to do this:
    integerBox1.intValue() > integerBox2.intValue()
    
    //в Java 5
    integerBox1 > integerBox2
  • müvafiq ibtidai qəbul edən bir üsulla sarğıya ötürüldükdə:

    public void exampleOfAutoboxing() {
       Long age = new Long(3);
       setAge(age);
    }
    
    public void setAge(long age) {
       this.age = age;
    }

22. Son açar söz nədir və onu harada istifadə etmək olar?

Açar söz finaldəyişənlər, metodlar və siniflər üçün istifadə edilə bilər.
  1. Son dəyişən başqa obyektə təyin edilə bilməz.
  2. son sinif sterildir)) varisləri ola bilməz.
  3. son metod bir əcdad üzərində ləğv edilə bilməz.
Biz zirvəni əhatə etdik, indi bunu daha ətraflı müzakirə edək.

son dəyişənlər

;Java bizə dəyişən yaratmaq və ona müəyyən dəyər təyin etmək üçün iki yol təqdim edir:
  1. Siz dəyişəni elan edə və sonra onu işə sala bilərsiniz.
  2. Siz dəyişəni elan edə və onu dərhal təyin edə bilərsiniz.
Bu hallar üçün son dəyişəndən istifadə nümunəsi:
public class FinalExample {

   //final static variable, which is immediately initialized:
   final static String FINAL_EXAMPLE_NAME = "I'm likely final one";

   //final is a variable that is not initialized, but will only work if
   //initialize this in the constructor:
   final long creationTime;

   public FinalExample() {
       this.creationTime = System.currentTimeMillis();
   }

   public static void main(String[] args) {
       FinalExample finalExample = new FinalExample();
       System.out.println(finalExample.creationTime);

       // final field FinalExample.FINAL_EXAMPLE_NAME cannot be assigned
//    FinalExample.FINAL_EXAMPLE_NAME = "Not you're not!";

       // final field Config.creationTime cannot be assigned
//    finalExample.creationTime = 1L;
   }
}

Son dəyişəni sabit hesab etmək olarmı?

Son dəyişənə yeni dəyər təyin edə bilməyəcəyimiz üçün, görünür, bunlar sabit dəyişənlərdir. Ancaq bu, yalnız ilk baxışdan görünür. Əgər dəyişənin istinad etdiyi məlumat növü dirsə immutable, bəli, sabitdir. Lakin məlumat növü mutabledəyişkəndirsə, metodlardan və dəyişənlərdən istifadə etməklə dəyişənin istinad etdiyi obyektin qiymətini dəyişmək mümkün olacaq finalvə bu halda onu sabit adlandırmaq olmaz. Beləliklə, nümunə göstərir ki, son dəyişənlərin bəziləri həqiqətən sabitdir, lakin bəziləri deyil və dəyişdirilə bilər.
public class FinalExample {

   //immutable final variables:
   final static String FINAL_EXAMPLE_NAME = "I'm likely final one";
   final static Integer FINAL_EXAMPLE_COUNT  = 10;

   // mutable filter variables
   final List<String> addresses = new ArrayList();
   final StringBuilder finalStringBuilder = new StringBuilder("constant?");
}

Yerli son dəyişənlər

finalDəyişən metod daxilində yaradıldıqda ona dəyişən local finaldeyilir:
public class FinalExample {

   public static void main(String[] args) {
       // This is how you can
       final int minAgeForDriveCar = 18;

       // or you can do it this way, in the foreach loop:
       for (final String arg : args) {
           System.out.println(arg);
       }
   }

}
Açar sözdən finaluzadılmış döngədə istifadə edə bilərik for, çünki döngənin iterasiyasını tamamladıqdan sonra forhər dəfə yeni dəyişən yaradılır. Lakin bu, normal for loopuna aid edilmir, ona görə də aşağıdakı kod kompilyasiya vaxtı xətası yaradacaq.
// final local changed j cannot be assigned
for (final int i = 0; i < args.length; i ++) {
   System.out.println(args[i]);
}

Yekun sinif

kimi elan edilmiş sinfi genişləndirə bilməzsiniz final. Sadə dillə desək, heç bir sinif bundan miras qala bilməz. finalJDK-da bir sinifin əla nümunəsidir String. finalDəyişməz sinif yaratmaq üçün ilk addım onu ​​genişləndirmək mümkün olmayan kimi qeyd etməkdir :
public final class FinalExample {
}

// Compilation error here
class WantsToInheritFinalClass extends FinalExample {
}

Yekun üsullar

Metod yekun olaraq qeyd edildikdə, o, yekun metod adlanır (məntiqi, eləmi?). Nəsil sinfində Final metodu ləğv edilə bilməz. Yeri gəlmişkən, Object sinfində metodlar - wait() və notify() - sondur, ona görə də bizim onları ləğv etmək imkanımız yoxdur.
public class FinalExample {
   public final String generateAddress() {
       return "Some address";
   }
}

class ChildOfFinalExample extends FinalExample {

   // compile error here
   @Override
   public String generateAddress() {
       return "My OWN Address";
   }
}

Java-da finalı necə və harada istifadə etmək olar

  • bəzi sinif səviyyəli sabitləri müəyyən etmək üçün final açar sözündən istifadə edin;
  • onların dəyişdirilməsini istəmədiyiniz zaman obyektlər üçün son dəyişənlər yaradın. Məsələn, giriş məqsədləri üçün istifadə edə biləcəyimiz obyektə xas xüsusiyyətlər;
  • sinifin uzadılmasını istəmirsinizsə, onu yekun olaraq qeyd edin;
  • dəyişməz< sinfi yaratmaq lazımdırsa, onu yekunlaşdırmalısınız;
  • metodun həyata keçirilməsinin onun törəmələrində dəyişməməsini istəyirsinizsə, metodu olaraq təyin edin final. Bu, icranın dəyişməməsi üçün çox vacibdir.

23. Dəyişən dəyişməz nədir?

Dəyişən

Dəyişən, vəziyyətləri və dəyişənləri yaradıldıqdan sonra dəyişdirilə bilən obyektlərdir. Məsələn, StringBuilder, StringBuffer kimi siniflər. Misal:
public class MutableExample {

   private String address;

   public MutableExample(String address) {
       this.address = address;
   }

   public String getAddress() {
       return address;
   }

   // this setter can change the name field
   public void setAddress(String address) {
       this.address = address;
   }

   public static void main(String[] args) {

       MutableExample obj = new MutableExample("first address");
       System.out.println(obj.getAddress());

       // update the name field, so this is a mutable object
       obj.setAddress("Updated address");
       System.out.println(obj.getAddress());
   }
}

Dəyişməz

Dəyişməzlər obyekt yaradıldıqdan sonra vəziyyətləri və dəyişənləri dəyişdirilə bilməyən obyektlərdir. Niyə HashMap üçün əla açar olmasın, elə deyilmi?) Məsələn, String, Integer, Double və s. Misal:
// make this class final so no one can change it
public final class ImmutableExample {

   private String address;

   ImmutableExample (String address) {
       this.address = address;
   }

   public String getAddress() {
       return address;
   }

   //remove the setter

   public static void main(String[] args) {

       ImmutableExample obj = new ImmutableExample("old address");
       System.out.println(obj.getAddress());

       // Therefore, do not change this field in any way, so this is an immutable object
       // obj.setName("new address");
       // System.out.println(obj.getName());

   }
}

24. Dəyişməz sinif necə yazılır?

Dəyişən və dəyişməz obyektlərin nə olduğunu anladıqdan sonra növbəti sual təbiidir - onu necə yazmaq olar? Dəyişməz dəyişməz sinif yazmaq üçün sadə addımları yerinə yetirməlisiniz:
  • sinfi yekunlaşdırın.
  • bütün sahələri özəl edin və onlar üçün yalnız alıcılar yaradın. Setterlər, əlbəttə ki, lazım deyil.
  • Bütün dəyişkən sahələri yekunlaşdırın ki, dəyər yalnız bir dəfə təyin olunsun.
  • dərin surəti yerinə yetirərək konstruktor vasitəsilə bütün sahələri işə salın (yəni obyektin özünün, onun dəyişənlərinin, dəyişənlərin dəyişənlərinin və s. surətinin çıxarılması)
  • faktiki obyektlərə istinadlar deyil, yalnız dəyərlərin nüsxələrini qaytarmaq üçün alıcılarda dəyişən dəyişən obyektləri klonlayın.
Misal:
/**
* An example of creating an immutable object.
*/
public final class FinalClassExample {

   private final int age;

   private final String name;

   private final HashMap<String, String> addresses;

   public int getAge() {
       return age;
   }


   public String getName() {
       return name;
   }

   /**
    * Clone the object before returning it.
    */
   public HashMap<String, String> getAddresses() {
       return (HashMap<String, String>) addresses.clone();
   }

   /**
    * In the constructor, deep copy the mutable objects.
    */
   public FinalClassExample(int age, String name, HashMap<String, String> addresses) {
       System.out.println("Performing a deep copy in the constructor");
       this.age = age;
       this.name = name;
       HashMap<String, String> temporaryMap = new HashMap<>();
       String key;
       Iterator<String> iterator = addresses.keySet().iterator();
       while (iterator.hasNext()) {
           key = iterator.next();
           temporaryMap.put(key, addresses.get(key));
       }
       this.addresses = temporaryMap;
   }
}
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION