JavaRush /Java blogi /Random-UZ /Eng yaxshi 50 Java asosiy intervyu savollari va javoblari...

Eng yaxshi 50 Java asosiy intervyu savollari va javoblari. 1-qism

Guruhda nashr etilgan
Hammaga salom, xonimlar va janoblar dasturiy ta'minot muhandislari! Keling, intervyu savollari haqida gapiraylik. Nimaga tayyorgarlik ko'rishingiz va nimani bilishingiz kerakligi haqida. Bu ushbu fikrlarni noldan takrorlash yoki o'rganish uchun ajoyib sababdir. Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-1-qismMenda OOP, Java sintaksisi, Java-dagi istisnolar, to'plamlar va multithreading haqida tez-tez beriladigan savollarning juda keng to'plami bor, ularni qulaylik uchun bir necha qismlarga ajrataman. Muhim:biz faqat 8 gacha bo'lgan Java versiyalari haqida gapiramiz. Bu erda 9, 10, 11, 12, 13 dan boshlab barcha yangiliklar hisobga olinmaydi. Javoblarni yaxshilash bo'yicha har qanday g'oyalar/sharhlar qabul qilinadi . Baxtli o'qish, ketaylik!

Java intervyusi: OOP savollari

1. Java qanday funksiyalarga ega?

Javob:
  1. OOP tushunchalari:

    1. ob'ektga yo'naltirilganlik;
    2. meros olish;
    3. inkapsulyatsiya;
    4. polimorfizm;
    5. abstraksiya.
  2. O'zaro platformalar: Java dasturi har qanday platformada hech qanday o'zgartirishlarsiz ishga tushirilishi mumkin. Sizga kerak bo'lgan yagona narsa - o'rnatilgan JVM (java virtual mashinasi).

  3. Yuqori unumdorlik: JIT (Just In Time kompilyator) yuqori ishlash imkonini beradi. JIT bayt kodini mashina kodiga o'zgartiradi va keyin JVM ijroni boshlaydi.

  4. Multithreading: deb nomlanuvchi ijro ishi Thread. JVM deb nomlangan ipni yaratadi main thread. Dasturchi Thread sinfidan meros olish yoki interfeysni amalga oshirish orqali bir nechta mavzularni yaratishi mumkin Runnable.

2. Meros degani nima?

Meros degani, bir sinf boshqa sinfni meros qilib olishi mumkin (“ kengaytiradi ”). Shunday qilib, siz meros qilib olgan sinfdagi kodni qayta ishlatishingiz mumkin. Mavjud sinf sifatida tanilgan superclassva yaratilgan sinf sifatida tanilgan subclass. Ular ham aytadilar parentva child.
public class Animal {
   private int age;
}

public class Dog extends Animal {

}
qayerda Animalva - . parent_Dogchild

3. Inkapsulyatsiya nima?

Bu savol ko'pincha Java dasturchisi intervyularida paydo bo'ladi. Inkapsulyatsiya kirish modifikatorlari, qabul qiluvchilar va sozlagichlar yordamida amalga oshirishni yashiradi. Bu ishlab chiquvchilar zarur deb hisoblagan joylarda tashqi foydalanish uchun kirishni yopish uchun amalga oshiriladi. Hayotdan foydalanish mumkin bo'lgan misol - bu avtomobil. Dvigatelning ishlashiga bevosita kirish imkonimiz yo'q. Biz uchun ish kalitni kontaktga qo'yish va dvigatelni yoqishdir. Va kaput ostida qanday jarayonlar sodir bo'lishi bizning ishimiz emas. Bundan tashqari, bizning ushbu faoliyatga aralashuvimiz oldindan aytib bo'lmaydigan vaziyatga olib kelishi mumkin, buning natijasida biz mashinani sindirib, o'zimizga zarar etkazishimiz mumkin. Aynan shu narsa dasturlashda sodir bo'ladi. Vikipediyada yaxshi tasvirlangan . JavaRush -da kapsülleme haqida maqola ham mavjud .

4. Polimorfizm nima?

Polimorfizm - dasturning bir xil interfeysga ega bo'lgan ob'ektlardan ushbu ob'ektning o'ziga xos turi haqida ma'lumotsiz bir xil foydalanish qobiliyati. Ular aytganidek, bitta interfeys - ko'plab ilovalar. Polimorfizm bilan siz har xil turdagi ob'ektlarni umumiy xatti-harakatlari asosida birlashtira olasiz va ulardan foydalanishingiz mumkin. Masalan, bizda "Hayvon" sinfi bor, uning ikkita avlodi bor - It va Mushuk. Umumiy Hayvonlar sinfi hamma uchun umumiy xulq-atvorga ega - ovoz chiqaring. Hayvonlar sinfining barcha avlodlarini birlashtirish va "tovush qilish" usulini bajarish kerak bo'lganda, biz polimorfizm imkoniyatlaridan foydalanamiz. Bu shunday ko'rinadi:
List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Shunday qilib, polimorfizm bizga yordam beradi. Bundan tashqari, bu polimorfik (ortiqcha yuklangan) usullarga ham tegishli. Polimorfizmdan foydalanish amaliyoti

Intervyu savollari - Java sintaksisi

5. Java tilida konstruktor nima?

Quyidagi xususiyatlar amal qiladi:
  1. Yangi obyekt yaratilganda dastur buning uchun tegishli konstruktordan foydalanadi.
  2. Konstruktor usulga o'xshaydi. Uning o'ziga xosligi shundaki, qaytaruvchi element (jumladan, void) yo'q va uning nomi sinf nomi bilan bir xil.
  3. Agar konstruktor aniq yozilmasa, avtomatik ravishda bo'sh konstruktor yaratiladi.
  4. Konstruktorni bekor qilish mumkin.
  5. Agar parametrlari bo'lgan konstruktor yaratilgan bo'lsa, lekin parametrsiz ham kerak bo'lsa, u avtomatik ravishda yaratilmagani uchun alohida yozilishi kerak.

6. Qaysi ikkita sinf Ob'ektdan meros bo'lmaydi?

Provokatsiyalarga aldanmang, bunday sinflar yo'q: barcha sinflar to'g'ridan-to'g'ri yoki ajdodlar orqali Ob'ekt sinfidan meros bo'lib o'tgan!

7. Lokal o‘zgaruvchi nima?

Java dasturchisi intervyusida yana bir mashhur savol. Mahalliy o'zgaruvchi - bu usul ichida aniqlangan va usul bajarilgunga qadar mavjud bo'lgan o'zgaruvchi. Amalga oshirish tugagach, mahalliy o'zgaruvchi mavjud bo'lishni to'xtatadi. Mana main() usulida helloMessage mahalliy o'zgaruvchisidan foydalanadigan dastur:
public static void main(String[] args) {
   String helloMessage;
   helloMessage = "Hello, World!";
   System.out.println(helloMessage);
}

8. Instance Variable nima?

Instance Variable - bu sinf ichida aniqlangan o'zgaruvchi va u ob'ekt mavjud bo'lgunga qadar mavjud. Misol tariqasida, nectarCapacity va maxNectarCapacity ikkita o'zgaruvchiga ega bo'lgan Bee sinfini keltirish mumkin:
public class Bee {

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

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

  ...
}

9. Kirish modifikatorlari nima?

Kirish modifikatorlari sinflar, usullar va o'zgaruvchilarga kirishni sozlash imkonini beruvchi vositadir. Kirishni oshirish tartibida quyidagi modifikatorlar mavjud:
  1. private- usullar, maydonlar va konstruktorlar uchun ishlatiladi. Kirish darajasi faqat u e'lon qilingan sinfdir.
  2. package-private(default)- darslar uchun foydalanish mumkin. Faqat sinf, usul, o'zgaruvchi, konstruktor e'lon qilingan muayyan paketga kirish.
  3. protectedpackage-private- modifikatorli sinfdan meros bo'lib qolgan sinflar uchun + bilan bir xil kirish protected.
  4. public- darslar uchun ham ishlatiladi. Butun ilova bo'ylab to'liq kirish.
  5. Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-2 qism

10. Ustivor usullar nima?

Usulni bekor qilish bola ota-ona sinfining xatti-harakatlarini o'zgartirmoqchi bo'lganda sodir bo'ladi. Agar siz ota-ona usulida bo'lgan narsani bajarishingiz kerak bo'lsa, bolada super.methodName() kabi konstruktsiyadan foydalanishingiz mumkin, bu ota-ona usulining ishini bajaradi va shundan keyingina mantiq qo'shing. Qo'llanilishi kerak bo'lgan talablar:
  • usul imzosi bir xil bo'lishi kerak;
  • qaytish qiymati bir xil bo'lishi kerak.

11. Usul imzosi nima?

Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-3 qismUsul imzosi - bu usul nomi va usul qabul qiladigan argumentlar to'plami. Usul imzosi usullarni haddan tashqari yuklashda usul uchun noyob identifikatordir.

12. Usulni ortiqcha yuklash nima?

Usulning haddan tashqari yuklanishi - bu polimorfizmning xususiyati bo'lib, unda usul imzosini o'zgartirish orqali siz bir xil harakatlar uchun turli usullarni yaratishingiz mumkin:
  • bir xil usul nomi;
  • turli dalillar;
  • boshqa qaytish turi bo'lishi mumkin.
Misol uchun, xuddi shunday add()haddan ArrayListtashqari yuklanishi mumkin va kiruvchi argumentlarga qarab qo'shishni boshqa yo'l bilan amalga oshiradi:
  • add(Object o)- oddiygina ob'ektni qo'shadi;
  • add(int index, Object o)— ob'ektni ma'lum bir indeksga qo'shadi;
  • add(Collection<Object> c)— ob'ektlar ro'yxatini qo'shadi;
  • add(int index, Collection<Object> c)— ma'lum bir indeksdan boshlab ob'ektlar ro'yxatini qo'shadi.

13. Interfeys nima?

Java-da bir nechta merosxo'rlik amalga oshirilmaydi, shuning uchun bu muammoni bartaraf etish uchun biz bilgan interfeyslar qo'shildi;) Uzoq vaqt davomida interfeyslarda faqat ularni amalga oshirmagan usullar mavjud edi. Ushbu javobning bir qismi sifatida biz ular haqida gaplashamiz. Masalan:

public interface Animal {
   void makeSound();
   void eat();
   void sleep();
}
Bundan ba'zi nuanslar kelib chiqadi:
  • interfeysdagi barcha usullar ommaviy va mavhum;
  • barcha o'zgaruvchilar umumiy statik yakuniy;
  • sinflar ularni meros qilib olmaydi (kengaytiradi), lekin ularni amalga oshiradi (amalga oshiradi). Bundan tashqari, siz xohlagancha ko'p interfeyslarni amalga oshirishingiz mumkin.
  • interfeysni amalga oshiradigan sinflar interfeysga ega bo'lgan barcha usullarni amalga oshirishni ta'minlashi kerak.
Mana bunday:
public class Cat implements Animal {
   public void makeSound() {
       // method implementation
   }

   public void eat() {
       // implementation
   }

   public void sleep() {
       // implementation
   }
}

14. Interfeysda standart usul nima?

Endi standart usullar haqida gapiraylik. Nima uchun, kim uchun? Bu usullar hamma narsani "sizniki ham, bizniki" qilish uchun qo'shilgan. Men nima haqida gapiryapman? Ha, bir tomondan, yangi funksiyalarni qo'shish kerak edi: lambdalar, Stream API, boshqa tomondan, Java mashhur bo'lgan narsani - orqaga qarab muvofiqlikni qoldirish kerak edi. Buning uchun interfeyslarga tayyor echimlarni kiritish kerak edi. Standart usullar bizga shunday keldi. Ya'ni, standart usul - bu kalit so'zga ega bo'lgan interfeysda amalga oshirilgan usul default. stream()Misol uchun, .dagi taniqli usul Collection. Buni tekshiring, bu interfeys ko'rinadigan darajada oddiy emas;). Yoki dan teng darajada taniqli forEach()usul Iterable. Standart usullar qo'shilmaguncha u ham mavjud emas edi. Aytgancha, bu haqda JavaRush -da ham o'qishingiz mumkin .

15. Qanday qilib ikkita bir xil standart usulni meros qilib olish mumkin?

Standart usul nima ekanligi haqidagi oldingi javobga asoslanib, siz boshqa savol berishingiz mumkin. Agar siz interfeyslarda usullarni amalga oshira olsangiz, nazariy jihatdan bir xil usul bilan ikkita interfeysni amalga oshirishingiz mumkin va buni qanday qilish kerak? Xuddi shu usulga ega ikki xil interfeys mavjud:
interface A {
   default void foo() {
       System.out.println("Foo A");
   }
}

interface B {
   default void foo() {
       System.out.println("Foo B");
   }
}
Va bu ikki interfeysni amalga oshiradigan sinf mavjud. foo()Noaniqlikdan qochish va kodni kompilyatsiya qilish uchun biz sinfdagi usulni bekor qilishimiz kerak va biz undagi har qanday interfeysning Cusulini oddiygina chaqirishimiz mumkin - yoki . Lekin faqat qanday qilib ma'lum bir interfeys usulini tanlash kerak yoki ? Buning uchun shunday tuzilma mavjud : foo()ABАВA.super.foo()
public class C implements A, B {
   @Override
   public void foo() {
       A.super.foo();
   }
}
yoki:
public class C implements A, B {
   @Override
   public void foo() {
       B.super.foo();
   }
}
Shunday qilib, foo()sinf usuli interfeysdagi standart usuldan yoki interfeysdan usuldan Cfoydalanadi . foo()Afoo()B

16. Abstrakt usullar va sinflar nima?

abstractJava-da mavhum sinflar va usullarni bildirish uchun ishlatiladigan zahiralangan so'z mavjud . Birinchidan, ba'zi ta'riflar. abstractAbstrakt usul - bu abstrakt sinfda kalit so'z bilan amalga oshirilmasdan yaratilgan usul . Ya'ni, bu interfeysdagi kabi usul, faqat kalit so'z qo'shilishi bilan, masalan:
public abstract void foo();
abstractMavhum sinf - bu quyidagi so'zga ega bo'lgan sinf :
public abstract class A {

}
Abstrakt sinf bir nechta xususiyatlarga ega:
  • ob'ektni uning asosida yaratish mumkin emas;
  • u mavhum usullarga ega bo'lishi mumkin;
  • u mavhum usullarga ega bo'lmasligi mumkin.
Mavhum sinflar qandaydir abstraksiyani (tavtologiya uchun uzr) umumlashtirish uchun kerak, bu real hayotda mavjud emas, lekin u juda ko'p umumiy xatti-harakatlar va holatlarni (ya'ni, usullar va o'zgaruvchilar) o'z ichiga oladi. Hayotdan ko'proq misollar keltirish mumkin. Hamma narsa atrofimizda. Bu "hayvon", "avtomobil", "geometrik shakl" va boshqalar bo'lishi mumkin.

17. String, String Builder va String Buffer o'rtasidagi farq nima?

Qiymatlar Stringdoimiy simli hovuzda saqlanadi. Bir qator yaratilgandan so'ng, u ushbu hovuzda paydo bo'ladi. Va uni yo'q qilish mumkin bo'lmaydi. Masalan:
String name = "book";
...oʻzgaruvchi satrlar hovuziga murojaat qiladi Doimiy qatorlar hovuzi Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-4 qism Agar siz oʻzgaruvchi nomini boshqa qiymatga oʻrnatsangiz, siz quyidagilarni olasiz:
name = "pen";
Doimiy simli hovuz Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-5 qismShunday qilib, bu ikki qiymat o'sha erda qoladi. String buferi:
  • qiymatlar Stringstekda saqlanadi. Agar qiymat o'zgartirilsa, yangi qiymat eskisiga almashtiriladi;
  • String Buffersinxronlashtirilgan va shuning uchun ip xavfsiz;
  • Ip xavfsizligi tufayli ishlash tezligi juda ko'p narsani talab qiladi.
Misol:
StringBuffer name = "book";
Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-6 qismNomning qiymati o'zgarishi bilan stekdagi qiymat o'zgaradi: Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-7 qismStringBuilder bilan aynan bir xil StringBuffer, faqat u ip xavfsiz emas. Shuning uchun uning tezligi ga nisbatan aniq yuqoriroqdir StringBuffer.

18. Abstrakt sinfning interfeysdan farqi nimada?

Abstrakt sinf:
  • mavhum sinflar standart konstruktorga ega; har safar ushbu mavhum sinfning bolasi yaratilganda chaqiriladi;
  • mavhum va mavhum bo'lmagan usullarni o'z ichiga oladi. Umuman olganda, u mavhum usullarni o'z ichiga olmaydi, lekin baribir mavhum sinf bo'lishi mumkin;
  • mavhumdan meros bo'lgan sinf faqat mavhum usullarni amalga oshirishi kerak;
  • mavhum sinfda misol o'zgaruvchisi bo'lishi mumkin (5-savolga qarang).
Interfeys:
  • konstruktorga ega emas va uni ishga tushirish mumkin emas;
  • faqat mavhum usullar qo'shilishi kerak (standart usullarni hisobga olmaganda);
  • interfeysni amalga oshiradigan sinflar barcha usullarni amalga oshirishi kerak (standart usullarni hisobga olmaganda);
  • interfeyslar faqat konstantalarni o'z ichiga olishi mumkin.

19. Nima uchun massivdagi elementga kirish O(1) ni oladi?

Bu savol so'nggi intervyudan olingan. Keyinchalik bilib olganimdek, bu savol inson qanday fikrda ekanligini bilish uchun beriladi. Bu bilimda amaliy ma'no kamligi aniq: bu haqiqatni bilishning o'zi kifoya. Birinchidan, biz aniqlab olishimiz kerakki, O (1) - bu operatsiya doimiy vaqtda sodir bo'lgan algoritmning vaqt murakkabligi uchun belgi. Ya'ni, bu belgi eng tez bajarilishdir. Bu savolga javob berish uchun biz massivlar haqida nimani bilishimizni tushunishimiz kerak? Massiv yaratish uchun intbiz quyidagilarni yozishimiz kerak:
int[] intArray = new int[100];
Ushbu yozuvdan bir nechta xulosalar chiqarish mumkin:
  1. Massiv yaratishda uning turi ma'lum bo'ladi.Agar turi ma'lum bo'lsa, massivning har bir katagi qanday o'lchamda bo'lishi aniq bo'ladi.
  2. Massiv qanday hajmda bo'lishi ma'lum.
Bundan kelib chiqadi: qaysi katakka yozishni tushunish uchun siz faqat qaysi xotira maydoniga yozishni hisoblashingiz kerak. Avtomobil uchun bu osonroq bo'lishi mumkin emas. Mashinada ajratilgan xotiraning boshlanishi, bir qator elementlar va bitta hujayra o'lchami mavjud. Bundan ko'rinib turibdiki, ro'yxatga olish maydoni massivning boshlang'ich joyiga + katak o'lchamining uning o'lchamiga ko'paytirilganiga teng bo'ladi.

ArrayList-dagi ob'ektlarga kirishda O (1) ni qanday olasiz?

Bu savol darhol oldingi savolga javob beradi. To'g'ri, biz massiv bilan ishlaganimizda va u erda primitivlar mavjud bo'lsa, biz bu tip yaratilganda qanday o'lchamda bo'lishini oldindan bilib olamiz. Ammo rasmdagi kabi sxema bo'lsa nima bo'ladi: Eng yaxshi 50 Java asosiy intervyu savollari va javoblari.  1-8 qismva biz A tipidagi elementlardan iborat to'plam yaratmoqchimiz va turli xil ilovalarni qo'shmoqchimiz - B, C, D:
List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
Bunday holatda, har bir hujayraning o'lchami qanday bo'lishini qanday tushunish mumkin, chunki har bir ob'ekt har xil bo'ladi va turli xil qo'shimcha maydonlarga ega bo'lishi mumkin (yoki butunlay boshqacha). Nima qilish kerak? Bu yerda savol chalkash va chalkashtirib yuboradigan tarzda qo'yilgan. Biz bilamizki, aslida kollektsiya ob'ektlarni saqlamaydi, faqat ushbu ob'ektlarga havolalar. Va barcha havolalar bir xil o'lchamga ega va u ma'lum. Shunday qilib, bu erda bo'sh joyni hisoblash avvalgi savolda bo'lgani kabi ishlaydi.

21. Avtoboks va qutidan chiqarish

Tarixiy ma'lumot: autoboxing va autounboxing JDK 5 ning asosiy yangiliklaridan biridir. Autoboxing - bu ibtidoiy turdan tegishli o'rash sinfiga avtomatik o'tkazish jarayoni. Avtomatik qutidan chiqarish - avtomatik boksning mutlaqo teskarisini qiladi - o'rash sinfini primitivga aylantiradi. Lekin agar o'rash qiymati bo'lsa null, unda paketni ochish paytida istisno tashlanadi NullPointerException.

Mos keladigan ibtidoiy - o'rash

Ibtidoiy O'rash sinfi
mantiqiy Mantiqiy
int Butun son
bayt Bayt
char Xarakter
suzmoq Float
uzoq Uzoq
qisqa Qisqa
ikki barobar Ikki marta

Avtomatik qadoqlash sodir bo'ladi:

  • o'rash sinfiga ibtidoiy havolani tayinlashda:

    Java 5 dan oldin:

    //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
    }
  • ibtidoiyni o'rashni kutadigan usulga argument sifatida o'tkazishda:

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

Avtomatik ochish sodir bo'ladi:

  • biz o'rash sinfiga ibtidoiy o'zgaruvchini tayinlaganimizda:

    //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 amallar bajarilgan hollarda. Ular faqat ibtidoiy turlarga tegishli, buning uchun siz ibtidoiyni ochishingiz kerak.

    // 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
  • mos keladigan primitivni qabul qiladigan usulda o'ramga o'tkazilganda:

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

22. Yakuniy kalit so'z nima va uni qayerda ishlatish kerak?

Kalit so'z finalo'zgaruvchilar, usullar va sinflar uchun ishlatilishi mumkin.
  1. Yakuniy o'zgaruvchini boshqa ob'ektga qayta belgilash mumkin emas.
  2. oxirgi sinf steril)) uning merosxo'rlari bo'lishi mumkin emas.
  3. oxirgi usulni ajdodda bekor qilib bo'lmaydi.
Biz yuqorida aytib o'tdik, endi bu haqda batafsilroq gaplashamiz.

yakuniy o'zgaruvchilar

;Java bizga o'zgaruvchini yaratish va unga qandaydir qiymat berishning ikkita usulini beradi:
  1. Siz o'zgaruvchini e'lon qilishingiz va uni keyinroq ishga tushirishingiz mumkin.
  2. Siz o'zgaruvchini e'lon qilishingiz va uni darhol belgilashingiz mumkin.
Ushbu holatlar uchun yakuniy o'zgaruvchidan foydalanishga misol:
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;
   }
}

Yakuniy o'zgaruvchini doimiy deb hisoblash mumkinmi?

Yakuniy o'zgaruvchiga yangi qiymat bera olmasligimiz sababli, ular doimiy o'zgaruvchilar kabi ko'rinadi. Ammo bu faqat birinchi qarashda. Agar o'zgaruvchi tegishli ma'lumotlar turi bo'lsa immutable, ha, u doimiy hisoblanadi. Ammo agar ma'lumotlar turi mutableo'zgaruvchan bo'lsa, usullar va o'zgaruvchilar yordamida o'zgaruvchi tegishli bo'lgan ob'ektning qiymatini o'zgartirish mumkin bo'ladi finalva bu holda uni doimiy deb atash mumkin emas. Shunday qilib, misol shuni ko'rsatadiki, ba'zi yakuniy o'zgaruvchilar haqiqatan ham doimiydir, lekin ba'zilari emas va ularni o'zgartirish mumkin.
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?");
}

Mahalliy yakuniy o'zgaruvchilar

finalUsul ichida o'zgaruvchi yaratilsa, u o'zgaruvchi local finaldeyiladi:
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);
       }
   }

}
finalKalit so'zni kengaytirilgan tsiklda ishlatishimiz mumkin for, chunki tsiklning iteratsiyasini tugatgandan so'ng, forhar safar yangi o'zgaruvchi yaratiladi. Lekin bu normal for loopiga taalluqli emas, shuning uchun quyidagi kod kompilyatsiya vaqtida xatolikka yo'l qo'yadi.
// final local changed j cannot be assigned
for (final int i = 0; i < args.length; i ++) {
   System.out.println(args[i]);
}

Yakuniy sinf

sifatida e'lon qilingan sinfni kengaytira olmaysiz final. Oddiy qilib aytganda, hech qanday sinf bundan meros bo'lolmaydi. finalJDKdagi sinfning ajoyib namunasi String. finalO'zgarmas sinf yaratishning birinchi qadami uni kengaytirib bo'lmasligi uchun uni sifatida belgilashdir :
public final class FinalExample {
}

// Compilation error here
class WantsToInheritFinalClass extends FinalExample {
}

Yakuniy usullar

Usul yakuniy deb belgilansa, u yakuniy usul deb ataladi (mantiqiy, to'g'rimi?). Yakuniy usulni avlod sinfida bekor qilib bo'lmaydi. Aytgancha, Object sinfidagi usullar - wait() va notify() - yakuniy hisoblanadi, shuning uchun biz ularni bekor qilish imkoniga ega emasmiz.
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 finalni qanday va qayerda ishlatish kerak

  • ba'zi sinf darajasidagi konstantalarni aniqlash uchun final kalit so'zidan foydalaning;
  • ob'ektlarni o'zgartirishni xohlamasangiz, ular uchun yakuniy o'zgaruvchilarni yarating. Masalan, biz jurnalga yozish uchun foydalanishimiz mumkin bo'lgan ob'ektga xos xususiyatlar;
  • agar siz sinfni uzaytirishni xohlamasangiz, uni yakuniy deb belgilang;
  • agar siz o'zgarmas< sinfini yaratishingiz kerak bo'lsa, uni yakuniy qilishingiz kerak;
  • Agar siz usulning amalga oshirilishi uning avlodlarida o'zgarmasligini istasangiz, usulni sifatida belgilang final. Amalga oshirish o'zgarmasligini ta'minlash uchun bu juda muhimdir.

23. O'zgaruvchan o'zgarmas nima?

O'zgaruvchan

O'zgaruvchan ob'ektlar, ularning holati va o'zgaruvchilari yaratilgandan keyin o'zgartirilishi mumkin. Masalan, StringBuilder, StringBuffer kabi sinflar. Misol:
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());
   }
}

O'zgarmas

O'zgarmas - ob'ekt yaratilgandan keyin holati va o'zgaruvchilarini o'zgartirib bo'lmaydigan ob'ektlar. Nega HashMap uchun ajoyib kalit emas, to'g'rimi?) Masalan, String, Integer, Double va boshqalar. Misol:
// 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. O'zgarmas sinf qanday yoziladi?

O'zgaruvchan va o'zgarmas ob'ektlar nima ekanligini aniqlaganingizdan so'ng, keyingi savol tabiiydir - uni qanday yozish kerak? O'zgarmas o'zgarmas sinfni yozish uchun siz oddiy amallarni bajarishingiz kerak:
  • sinfni yakuniy qiling.
  • barcha maydonlarni shaxsiy qiling va ular uchun faqat qabul qiluvchilarni yarating. Setterlar, albatta, kerak emas.
  • Qiymat faqat bir marta o'rnatilishi uchun barcha o'zgaruvchan maydonlarni yakuniy qiling.
  • konstruktor orqali barcha maydonlarni ishga tushirish, chuqur nusxalashni amalga oshirish (ya'ni ob'ektning o'zini, uning o'zgaruvchilarini, o'zgaruvchilarning o'zgaruvchilarini va boshqalarni nusxalash)
  • Haqiqiy ob'ektlarga havolalarni emas, balki faqat qiymatlarning nusxalarini qaytarish uchun qabul qiluvchilarda o'zgaruvchan o'zgaruvchan ob'ektlarni klonlash.
Misol:
/**
* 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;
   }
}
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION