JavaRush /Java блогы /Random-KK /Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары. ...
Roman Beekeeper
Деңгей

Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары. 1 бөлім

Топта жарияланған
Баршаңызға сәлем, ханымдар мен мырзалар бағдарламалық қамтамасыз ету инженерлері! Сұхбат сұрақтары туралы сөйлесейік. Неге дайындалу керек және нені білу керектігі туралы. Бұл осы нүктелерді нөлден бастап қайталауға немесе зерттеуге тамаша себеп. Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1 - 1 бөлімМенде OOP, Java синтаксисі, Java тіліндегі ерекшеліктер, жинақтар және көп ағындылық туралы жиі қойылатын сұрақтардың жеткілікті кең жинағы бар, оларды ыңғайлы болу үшін бірнеше бөлікке бөлемін. Маңызды:біз тек 8-ге дейінгі Java нұсқалары туралы айтатын боламыз. Мұнда 9, 10, 11, 12, 13-тен бастап барлық жаңалықтар ескерілмейді. Жауаптарды жақсарту туралы кез келген идеялар/түсініктемелер қабылданады . Бақытты оқу, кеттік!

Java сұхбаты: OOP сұрақтары

1. Java тілінің қандай мүмкіндіктері бар?

Жауап:
  1. OOP тұжырымдамалары:

    1. нысанды бағдарлау;
    2. мұрагерлік;
    3. инкапсуляция;
    4. полиморфизм;
    5. абстракция.
  2. Кросс-платформа: Java бағдарламасын кез келген платформада ешбір өзгертусіз іске қосуға болады. Сізге қажет жалғыз нәрсе - орнатылған JVM (java виртуалды машинасы).

  3. Жоғары өнімділік: JIT (Just In Time компиляторы) жоғары өнімділікке мүмкіндік береді. JIT byte codeты машиналық codeқа түрлендіреді, содан кейін JVM орындауды бастайды.

  4. Multithreading: Орындау ағыны ретінде белгілі Thread. JVM деп аталатын ағынды жасайды main thread. Бағдарламашы Thread сыныбынан мұра алу немесе интерфейсті енгізу арқылы бірнеше ағындарды жасай алады Runnable.

2. Мұрагерлік дегеніміз не?

Мұрагерлік бір сыныптың басқа сыныпты мұра ете алатынын (« кеңейтеді ») білдіреді. Осылайша сіз мұрагер сыныптағы codeты қайта пайдалана аласыз. Қолданыстағы класс ретінде белгілі superclass, ал жасалып жатқан класс ретінде белгілі subclass. Олар сондай-ақ parentжәне дейді child.
public class Animal {
   private int age;
}

public class Dog extends Animal {

}
қайда Animal, parentжәне Dog- child.

3. Инкапсуляция дегеніміз не?

Бұл сұрақ Java әзірлеушілерімен сұхбат кезінде жиі туындайды. Инкапсуляция кіруді модификаторлар арқылы, қабылдаушылар мен орнатушылар арқылы жүзеге асыруды жасырады. Бұл әзірлеушілер қажет деп санайтын жерлерде сыртқы пайдалану үшін қолжетімділікті жабу үшін жасалады. Өмірден қол жетімді мысал - көлік. Қозғалтқыштың жұмысына тікелей қол жеткізе алмаймыз. Біз үшін жұмыс кілтті оталдыруға қойып, қозғалтқышты қосу. Ал капюшонның астында қандай процестер болатыны біздің шаруамыз емес. Оның үстіне, біздің бұл әрекетке араласуымыз күтпеген жағдайға әкелуі мүмкін, соның салдарынан біз көлікті бұзып, өзімізге зиян келтіруіміз мүмкін. Бағдарламалауда дәл осындай нәрсе орын алады. Уикипедияда жақсы сипатталған . JavaRush- те инкапсуляция туралы мақала да бар .

4. Полиморфизм дегеніміз не?

Полиморфизм - бағдарламаның интерфейсі бірдей an objectілерді сол an objectінің нақты түрі туралы ақпаратсыз бірдей пайдалану мүмкіндігі. Олар айтқандай, бір интерфейс - көптеген іске асыру. Полиморфизммен сіз олардың жалпы мінез-құлқына негізделген әртүрлі нысандарды біріктіріп, пайдалана аласыз. Мысалы, бізде Animal класы бар, оның екі ұрпағы бар - ит пен мысық. Жануарлардың жалпы класында барлығына ортақ мінез-құлық бар - дыбыс шығару. Жануарлар класының барлық ұрпақтарын біріктіріп, «дыбыс жасау» әдісін орындау қажет болған жағдайда, біз полиморфизм мүмкіндіктерін пайдаланамыз. Бұл келесідей болады:
List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Сондықтан полиморфизм бізге көмектеседі. Оның үстіне бұл полиморфты (артық жүктелген) әдістерге де қатысты. Полиморфизмді қолдану тәжірибесі

Сұхбат сұрақтары – Java синтаксисі

5. Java тілінде конструктор дегеніміз не?

Келесі сипаттамалар жарамды:
  1. Жаңа an object жасалғанда, бағдарлама мұны істеу үшін сәйкес конструкторды пайдаланады.
  2. Конструктор әдіс сияқты. Оның ерекшелігі - қайтаратын элемент жоқ (соның ішінде void) және оның атауы класс атауымен бірдей.
  3. Егер конструктор анық жазылмаса, бос конструктор автоматты түрде жасалады.
  4. Конструкторды қайта анықтауға болады.
  5. Егер параметрлері бар конструктор жасалған болса, бірақ ол параметрсіз де қажет болса, ол автоматты түрде жасалмағандықтан, бөлек жазылуы керек.

6. Объекттен қандай екі класс мұрагер емес?

Аранdateшылыққа алданбаңыз, мұндай класстар жоқ: барлық класстар тікелей немесе ата-бабалар арқылы Объект класынан мұраланған!

7. Жергілікті айнымалы дегеніміз не?

Java әзірлеушісімен сұхбат кезіндегі тағы бір танымал сұрақ. Жергілікті айнымалы - әдіс ішінде анықталған және әдіс орындалғанға дейін бар айнымалы. Орындау аяқталғаннан кейін жергілікті айнымалы өз жұмысын тоқтатады. Мұнда main() әдісінде helloMessage жергілікті айнымалысын қолданатын бағдарлама берілген:
public static void main(String[] args) {
   String helloMessage;
   helloMessage = "Hello, World!";
   System.out.println(helloMessage);
}

8. Дана айнымалысы дегеніміз не?

Айнымалы даналық – сынып ішінде анықталған айнымалы мән және ол нысан бар сәтке дейін бар. Мысал ретінде екі айнымалы nectarCapacity және maxNectarCapacity бар Bee сыныбын келтіруге болады:
public class Bee {

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

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

  ...
}

9. Қол жеткізу модификаторлары дегеніміз не?

Қатынас модификаторлары сыныптарға, әдістерге және айнымалыларға қатынасты теңшеуге мүмкіндік беретін құрал болып табылады. Қол жеткізуді арттыру ретімен реттелген келесі модификаторлар бар:
  1. private- әдістер, өрістер және конструкторлар үшін қолданылады. Қатынас деңгейі – ол жарияланған сынып қана.
  2. package-private(default)- сабақтарда қолдануға болады. Класс, әдіс, айнымалы, конструктор жарияланған белгілі бір бумада ғана қол жеткізу.
  3. protectedpackage-private— модификаторы бар сыныптан мұрагер болатын сыныптар үшін + сияқты рұқсат protected.
  4. public- сабақтар үшін де қолданылады. Бүкіл қолданбаға толық қол жеткізу.
  5. Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1-2 бөлім

10. Әдістерді қайталау дегеніміз не?

Әдісті қайта анықтау бала ата-аналық сыныптың әрекетін өзгерткісі келгенде орын алады. Егер сіз ата-аналық әдістің орындалғанын қаласаңыз, ата-аналық әдіс жұмысын орындайтын балада super.methodName() сияқты конструкцияны пайдалана аласыз, содан кейін ғана логиканы қосасыз. Орындалатын талаптар:
  • әдіс қолтаңбасы бірдей болуы керек;
  • қайтару мәні бірдей болуы керек.

11. Әдіс қолтаңбасы дегеніміз не?

Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1 - 3 бөлімӘдіс қолтаңбасы әдіс атауының және әдіс қабылдайтын аргументтердің жиынтығы болып табылады. Әдіс қолтаңбасы әдістерді шамадан тыс жүктеу кезінде әдіс үшін бірегей идентификатор болып табылады.

12. Әдістің шамадан тыс жүктелуі дегеніміз не?

Әдістің шамадан тыс жүктелуі - бұл әдіс қолтаңбасын өзгерту арқылы бірдей әрекеттер үшін әртүрлі әдістерді жасауға болатын полиморфизм қасиеті:
  • бірдей әдіс атауы;
  • әртүрлі аргументтер;
  • басқа қайтару түрі болуы мүмкін.
Мысалы, келесідей шамадан тыс жүктелуі add()мүмкін ArrayListжәне кіріс аргументтерге байланысты қосуды басқа жолмен орындайды:
  • add(Object o)- жай ғана an object қосады;
  • add(int index, Object o)— белгілі бір индекске an object қосады;
  • add(Collection<Object> c)— an objectілер тізімін қосады;
  • add(int index, Collection<Object> c)— белгілі бір индекстен бастап an objectілер тізімін қосады.

13. Интерфейс дегеніміз не?

Java-да бірнеше мұрагерлік іске асырылмайды, сондықтан бұл мәселені шешу үшін біз білетін интерфейстер қосылды;) Ұзақ уақыт бойы интерфейстерде оларды іске асырмайтын әдістер ғана болды. Бұл жауаптың бөлігі ретінде біз олар туралы сөйлесетін боламыз. Мысалы:

public interface Animal {
   void makeSound();
   void eat();
   void sleep();
}
Осыдан кейбір нюанстар шығады:
  • интерфейстегі барлық әдістер ашық және дерексіз;
  • барлық айнымалылар жалпыға ортақ статикалық соңғы болып табылады;
  • сыныптар оларды мұраға алмайды (кеңейтеді), бірақ оларды жүзеге асырады (іске асырады). Сонымен қатар, сіз қалағаныңызша көптеген интерфейстерді енгізе аласыз.
  • интерфейсті жүзеге асыратын сыныптар интерфейсте бар барлық әдістерді іске асыруды қамтамасыз етуі керек.
Бұл сияқты:
public class Cat implements Animal {
   public void makeSound() {
       // method implementation
   }

   public void eat() {
       // implementation
   }

   public void sleep() {
       // implementation
   }
}

14. Интерфейстегі әдепкі әдіс дегеніміз не?

Енді әдепкі әдістер туралы сөйлесейік. Не үшін, кім үшін? Бұл әдістер барлығын «сендікі де, біздікі де» ету үшін қосылды. Мен не туралы айтып отырмын? Иә, бір жағынан, жаңа функционалдылықты қосу қажет болды: lambdas, Stream API, екінші жағынан, Java-ның әйгілі болғанын қалдыру керек болды - кері үйлесімділік. Ол үшін интерфейстерге дайын шешімдерді енгізу қажет болды. Әдепкі әдістер бізге осылай келді. Яғни, әдепкі әдіс - кілт сөзі бар интерфейсте іске асырылған әдіс default. Мысалы , stream(). CollectionОны тексеріңіз, бұл интерфейс көрінгендей қарапайым емес;). forEach()Немесе сол сияқты белгілі әдіс Iterable. Әдепкі әдістер қосылғанға дейін ол да болған жоқ. Айтпақшы, бұл туралы JavaRush сайтында да оқуға болады .

15. Екі бірдей әдепкі әдісті қалай мұраға алуға болады?

Әдепкі әдіс қандай екендігі туралы алдыңғы жауапқа сүйене отырып, басқа сұрақ қоюға болады. Интерфейстерде әдістерді жүзеге асыра алсаңыз, теориялық тұрғыдан бірдей әдіспен екі интерфейсті жүзеге асыруға болады және мұны қалай жасауға болады? Бір әдіспен екі түрлі интерфейс бар:
interface A {
   default void foo() {
       System.out.println("Foo A");
   }
}

interface B {
   default void foo() {
       System.out.println("Foo B");
   }
}
Және осы екі интерфейсті жүзеге асыратын класс бар. Белгісіздікті болдырмау және codeты құрастыру үшін біз foo()сыныптағы әдісті қайта анықтауымыз керек Cжәне біз foo()ондағы кез келген интерфейстің әдісін - Aнемесе деп атауға болады B. Бірақ нақты интерфейс әдісін қалай таңдауға болады Анемесе В? Бұл үшін осындай құрылым бар A.super.foo():
public class C implements A, B {
   @Override
   public void foo() {
       A.super.foo();
   }
}
немесе:
public class C implements A, B {
   @Override
   public void foo() {
       B.super.foo();
   }
}
Осылайша, foo()сынып әдісі интерфейстегі әдепкі әдісті немесе интерфейстегі әдісті Cпайдаланады . foo()Afoo()B

16. Абстрактілі әдістер мен класстар дегеніміз не?

abstractJava-да абстрактілі сыныптар мен әдістерді белгілеу үшін пайдаланылатын сақталған сөз бар . Біріншіден, кейбір анықтамалар. abstractАбстрактілі әдіс – абстрактілі сыныптағы кілт сөзбен іске асырусыз жасалған әдіс . Яғни, бұл интерфейстегідей әдіс, тек кілт сөзді қосу арқылы, мысалы:
public abstract void foo();
abstractАбстрактілі класс - бұл келесі сөзі де бар класс :
public abstract class A {

}
Абстрактілі класс бірнеше мүмкіндіктерге ие:
  • оның негізінде an object құру мүмкін емес;
  • оның дерексіз әдістері болуы мүмкін;
  • оның дерексіз әдістері болмауы мүмкін.
Абстрактілі сыныптар нақты өмірде жоқ, бірақ көптеген жалпы мінез-құлық пен күйлерді (яғни, әдістер мен айнымалылар) қамтитын абстракцияның қандай да бір түрін (таутология үшін кешіріңіз) жалпылау үшін қажет. Өмірден мысалдар жетерлік. Барлығы біздің айналамызда. Бұл «жануар», «автокөлік», «геометриялық фигура» және т.б.

17. String, String Builder және String Buffer арасындағы айырмашылық неде?

Мәндер Stringтұрақты жол пулында сақталады. Жол жасалғаннан кейін ол осы пулда пайда болады. Және оны жою мүмкін болмайды. Мысалы:
String name = "book";
...айнымалы жол пулына сілтеме жасайды Тұрақты жол пулы Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1-4 бөлім Егер айнымалы атауын басқа мәнге орнатсаңыз, келесіні аласыз:
name = "pen";
Тұрақты жол пулы Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1 - 5 бөлімСондықтан бұл екі мән сол жерде қалады. Жол буфері:
  • мәндер Stringстекке сақталады. Егер мән өзгертілсе, онда жаңа мән ескімен ауыстырылады;
  • String Bufferсинхрондалған, сондықтан жіп қауіпсіз;
  • Жіптің қауіпсіздігіне байланысты жұмыс жылдамдығы көп нәрсені қаламайды.
Мысалы:
StringBuffer name = "book";
Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1-6 бөлімАтаудың мәні өзгерген кезде, стектегі мән өзгереді: Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1-7 бөлімStringBuilder -мен бірдей StringBuffer, тек ол ағын қауіпсіз емес. Сондықтан оның жылдамдығы -ға қарағанда жоғары екені анық StringBuffer.

18. Абстрактілі класс пен интерфейстің айырмашылығы неде?

Абстрактілі сынып:
  • абстрактілі сыныптарда әдепкі конструктор бар; ол осы абстрактілі сыныптың баласы құрылған сайын шақырылады;
  • абстрактілі және дерексіз әдістерді қамтиды. Жалпы алғанда, ол абстрактілі әдістерді қамтымауы мүмкін, бірақ бәрібір дерексіз класс болуы мүмкін;
  • абстрактіліден мұрагер класс тек абстрактілі әдістерді жүзеге асыруы керек;
  • дерексіз сынып айнымалы дананы қамтуы мүмкін (№5 сұрақты қараңыз).
Интерфейс:
  • конструкторы жоқ және оны инициализациялау мүмкін емес;
  • тек дерексіз әдістерді қосу керек (әдепкі әдістерді есептемегенде);
  • интерфейсті жүзеге асыратын сыныптар барлық әдістерді жүзеге асыруы керек (әдепкі әдістерді есептемегенде);
  • интерфейстер тек тұрақтыларды қамтуы мүмкін.

19. Неліктен массивтің элементіне қатынасу O(1) мәнін алады?

Бұл сұрақ соңғы сұхбаттан алынған. Кейін түсінгенімдей, бұл сұрақ адамның қалай ойлайтынын білу үшін қойылады. Бұл білімнің практикалық мағынасы аз екені анық: бұл фактіні білу жеткілікті. Біріншіден, O(1) амал тұрақты уақытта орындалатын алгоритмнің уақыт күрделілігін белгілеу екенін түсіндіруіміз керек . Яғни, бұл белгілеу ең жылдам орындалу болып табылады. Бұл сұраққа жауап беру үшін біз массивтер туралы не білетінімізді түсінуіміз керек? Массив құру үшін intкелесіні жазу керек:
int[] intArray = new int[100];
Бұл жазбадан бірнеше қорытынды жасауға болады:
  1. Массивті құру кезінде оның типі белгілі.Егер түрі белгілі болса, онда массивтің әрбір ұяшығы қандай өлшемде болатыны анық.
  2. Массив қандай өлшемде болатыны белгілі.
Бұдан шығатыны: қай ұяшыққа жазу керектігін түсіну үшін жадының қай аймағына жазу керектігін есептеу керек. Көлік үшін бұл оңай болуы мүмкін емес. Құрылғыда бөлінген жадтың бастауы, элементтер саны және бір ұяшық өлшемі бар. Бұдан жазу кеңістігі массивтің бастапқы орнына + ұяшықтың өлшемі оның өлшеміне көбейтілгеніне тең болатыны анық.

ArrayList ішіндегі нысандарға қатынасу кезінде O(1) қалай алуға болады?

Бұл сұрақ алдыңғы сұраққа бірден келеді. Рас, біз массивпен жұмыс істегенде және онда қарабайырлар бар болса, біз оның жасалған кезде бұл түрдің өлшемі қандай болатынын алдын ала білеміз. Бірақ бізде суреттегідей схема болса ше: Ең жақсы 50 Java негізгі сұхбат сұрақтары мен жауаптары.  1-8 бөлімжәне біз А типті элементтері бар коллекция жасап, әртүрлі іске асыруларды қосқымыз келеді - B, C, D:
List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
Бұл жағдайда әрбір ұяшықтың өлшемі қандай болатынын қалай түсінуге болады, өйткені әрбір нысан әртүрлі болады және әртүрлі қосымша өрістерге ие болуы мүмкін (немесе мүлдем басқаша). Не істеу? Бұл жерде сұрақ шатастырып, шатастыратындай етіп қойылған. Біз шын мәнінде коллекция an objectілерді сақтамайтынын, тек осы нысандарға сілтеме жасайтынын білеміз. Және барлық сілтемелердің өлшемі бірдей және ол белгілі. Сонымен, кеңістікті санау мұнда алдыңғы сұрақтағыдай жұмыс істейді.

21. Автобокс және қораптан шығару

Тарихи дерек: автобокс және автобоксинг JDK 5 негізгі инновацияларының бірі болып табылады. Автобокс - қарабайыр түрден тиісті орауыш класына автоматты түрлендіру процесі. Автоматты түрде жәшіктен шығару - автобоксқа мүлдем қарама-қарсы әрекетті жасайды - орауыш класын қарабайырға түрлендіреді. Бірақ егер орауыш мәні бар болса null, онда орамды ашу кезінде ерекше жағдай шығарылады NullPointerException.

Сәйкестік примитив - орауыш

Қарапайым Қаптама класы
логикалық Логикалық
int бүтін сан
byte Байт
таңба Кейіпкер
жүзу Қалқымалы
ұзақ Ұзақ
қысқа Қысқа
қос Қосарлы

Автоматты орау орын алады:

  • орауыш класына қарабайыр сілтеме тағайындағанда:

    Java 5-ке дейін:

    //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
    }
  • ораманы күтетін әдіске аргумент ретінде қарабайырды бергенде:

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

Автоматты түрде орамнан шығару орын алады:

  • орауыш класына қарабайыр айнымалыны тағайындағанда:

    //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;
  • Арифметикалық амалдар бар жағдайларда. Олар тек қарабайыр түрлерге қолданылады; ол үшін қарабайырға қорапты ашу керек.

    // 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
  • сәйкес примитивті қабылдайтын әдіспен қаптамаға өткенде:

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

22. Соңғы түйінді сөз дегеніміз не және оны қайда қолдануға болады?

Түйінді сөзді finalайнымалылар, әдістер және сыныптар үшін пайдалануға болады.
  1. Соңғы айнымалыны басқа нысанға қайта тағайындау мүмкін емес.
  2. соңғы сынып стерильді)) оның мұрагерлері болмайды.
  3. түпкілікті әдісті ата-бабада қайта анықтау мүмкін емес.
Біз жоғарғы жағын қарастырдық, енді оны толығырақ талқылайық.

соңғы айнымалылар

;Java бізге айнымалы жасаудың және оған қандай да бір мән тағайындаудың екі жолын береді:
  1. Айнымалы мәнді жариялауға және оны кейінірек инициализациялауға болады.
  2. Айнымалыны жариялауға және оны дереу тағайындауға болады.
Осы жағдайлар үшін соңғы айнымалы мәнді қолданатын мысал:
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;
   }
}

Соңғы айнымалыны тұрақты деп санауға бола ма?

Соңғы айнымалыға жаңа мән тағайындай алмайтындықтан, бұл тұрақты айнымалылар болып көрінеді. Бірақ бұл бірінші көзқараста ғана. Егер айнымалыға сілтеме жасайтын деректер түрі болса immutable, иә, ол тұрақты. Бірақ егер деректер түрі өзгермелі болса, әдістер мен айнымалыларды қолдану арқылы айнымалы сілтеме жасайтын mutableнысанның мәнін өзгертуге болады және бұл жағдайда оны тұрақты деп атауға болмайды. finalСонымен, мысал соңғы айнымалылардың кейбірі шын мәнінде тұрақты, бірақ кейбіреулері жоқ және оларды өзгертуге болатынын көрсетеді.
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?");
}

Жергілікті соңғы айнымалылар

finalӘдіс ішінде айнымалы жасалғанда, ол айнымалы local finalдеп аталады:
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);
       }
   }

}
finalБіз кілт сөзді кеңейтілген циклде пайдалана аламыз for, өйткені циклдің итерациясын аяқтағаннан кейін forәр жолы жаңа айнымалы жасалады. Бірақ бұл қалыпты for цикліне қолданылмайды, сондықтан төмендегі code компиляция уақытында қате жібереді.
// final local changed j cannot be assigned
for (final int i = 0; i < args.length; i ++) {
   System.out.println(args[i]);
}

Қорытынды сынып

ретінде жарияланған сыныпты кеңейте алмайсыз final. Қарапайым тілмен айтқанда, ешбір класс осыдан мұраға ие бола алмайды. finalJDK сыныптың тамаша мысалы болып табылады String. Өзгермейтін класс жасаудың бірінші қадамы оны finalкеңейтуге болмайтындай етіп белгілеу болып табылады:
public final class FinalExample {
}

// Compilation error here
class WantsToInheritFinalClass extends FinalExample {
}

Қорытынды әдістер

Әдіс соңғы деп белгіленсе, ол соңғы әдіс деп аталады (логикалық, дұрыс па?). Соңғы әдісті ұрпақ класында қайта анықтау мүмкін емес. Айтпақшы, Object класындағы әдістер – wait() және notify() – түпкілікті болып табылады, сондықтан оларды қайта анықтау мүмкіндігіміз жоқ.
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-да финалды қалай және қайда қолдануға болады

  • кейбір сынып деңгейіндегі тұрақтыларды анықтау үшін соңғы кілт сөзін пайдаланыңыз;
  • олардың өзгертілгенін қаламасаңыз, нысандар үшін соңғы айнымалы мәндерді жасаңыз. Мысалы, журнал жүргізу мақсаттары үшін пайдалануға болатын нысанға тән сипаттар;
  • егер сіз сыныптың ұзартылуын қаламасаңыз, оны соңғы деп белгілеңіз;
  • өзгермейтін< класын жасау қажет болса, оны түпкілікті ету керек;
  • егер әдісті жүзеге асыру оның ұрпақтарында өзгермеуін қаласаңыз, әдісті ретінде белгілеңіз final. Бұл іске асыру өзгермейтінін қамтамасыз ету үшін өте маңызды.

23. Өзгермейтін өзгермейтін дегеніміз не?

Өзгермелі

Өзгермелі - күйлері мен айнымалылары жасалғаннан кейін өзгертуге болатын нысандар. Мысалы, StringBuilder, StringBuffer сияқты сыныптар. Мысалы:
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());
   }
}

Өзгермейтін

Өзгермейтін - бұл an object жасалғаннан кейін күйлері мен айнымалылары өзгертілмейтін нысандар. Неліктен HashMap үшін тамаша кілт емес пе?) Мысалы, String, Integer, Double және т.б. Мысалы:
// 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. Өзгермейтін класс қалай жазылады?

Өзгермейтін және өзгермейтін нысандардың не екенін анықтағаннан кейін келесі сұрақ табиғи - оны қалай жазу керек? Өзгермейтін өзгермейтін класс жазу үшін қарапайым қадамдарды орындау керек:
  • сыныпты қорытындылау.
  • барлық өрістерді жеке етіп жасаңыз және олар үшін тек алушыларды жасаңыз. Сетерлер, әрине, қажет емес.
  • Мәнді тек бір рет орнатуға болатындай барлық өзгермелі өрістерді соңғы етіп жасаңыз.
  • конструктор арқылы барлық өрістерді инициализациялау, терең көшіруді орындау (яғни an objectінің өзін, оның айнымалыларын, айнымалылардың айнымалыларын және т.б. көшіру)
  • нақты нысандарға сілтемелерді емес, тек мәндердің көшірмелерін қайтару үшін қабылдағыштардағы өзгермелі айнымалы нысандарды клондаңыз.
Мысалы:
/**
* 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;
   }
}
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION