JavaRush /Java блогу /Random-KY /Топ 50 Java негизги интервью суроолору жана жооптору. 1-б...
Roman Beekeeper
Деңгээл

Топ 50 Java негизги интервью суроолору жана жооптору. 1-бөлүк

Группада жарыяланган
Баарыңарга салам, айымдар жана мырзалар Программалык камсыздоо инженерлери! Келгиле, интервью суроолору боюнча сүйлөшөлү. Сиз эмнеге даярданышыңыз керек жана эмнени бorшиңиз керектиги жөнүндө. Бул ушул пункттарды нөлдөн баштап кайталоо же изилдөө үчүн эң сонун себеп. Топ 50 Java негизги интервью суроолору жана жооптору.  1-1-бөлүкМенде OOP, Java синтаксиси, Javaдагы өзгөчөлүктөр, коллекциялар жана көп агым жөнүндө көп берилүүчү суроолордун кеңири жыйнагы бар, аларды ыңгайлуулук үчүн мен бир нече бөлүккө бөлөм. Маанилүү:биз 8ге чейинки Java versionлары жөнүндө гана сүйлөшөбүз. Бул жерде 9, 10, 11, 12, 13 жаңычылдыктар эске алынbyte. Жоопторду кантип жакшыртуу боюнча ар кандай идеялар/комментарийлер кабыл алынат . Бактылуу окуу, кеттик!

Java интервью: OOP суроолору

1. Java кандай өзгөчөлүктөргө ээ?

Жооп:
  1. OOP түшүнүктөрү:

    1. an objectиге багыт алуу;
    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 иштеп чыгуучуларынын интервьюларында пайда болот. Инкапсуляция, кирүү модификаторлорун колдонуу менен ишке ашырууну жашырып жатат, алуучу жана орнотуучуларды колдонуу. Бул иштеп чыгуучулар зарыл деп эсептеген жерлерде тышкы колдонууга кирүү мүмкүнчүлүгүн жабуу үчүн жасалат. Турмуштан жеткorктуу мисал – бул унаа. Кыймылдаткычтын иштешине түздөн-түз кире албайбыз. Биз үчүн жумуш ачкычты от алдыруу жана кыймылдаткычты иштетүү. Ал эми капоттун астында кандай процесстер болору биздин иш эмес. Анын үстүнө биздин бул ишке кийлигишкенибиз күтүүсүз кырдаалга алып келиши мүмкүн, анын кесепетинен биз унааны бузуп, өзүбүзгө зыян келтирип алабыз. Дал ушундай нерсе программалоодо болот. Wikipedia жакшы сүрөттөлгөн . JavaRush боюнча инкапсуляция жөнүндө макала да бар .

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

Полиморфизм – программанын ошол an objectтин конкреттүү түрү жөнүндө маалыматсыз эле интерфейси бар an objectтерди бирдей колдонуу мүмкүнчүлүгү. Алар айткандай, бир интерфейс - көптөгөн ишке ашыруу. Полиморфизм менен сиз an objectтердин ар кандай түрлөрүн алардын жалпы жүрүм-турумунун негизинде бириктирип, колдоно аласыз. Мисалы, бизде Animal классы бар, анын эки тукуму бар - Dog жана Cat. Жалпы Animal классынын бардыгы үчүн жалпы жүрүм-туруму бар - үн чыгаруу. Жаныбарлар классынын бардык урпактарын чогултуп, "үн чыгаруу" ыкмасын аткаруу керек болгон учурда, биз полиморфизмдин мүмкүнчүлүктөрүн колдонобуз. Бул кандай болот:
List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Ошентип, полиморфизм бизге жардам берет. Мындан тышкары, бул полиморфтук (ашыкча жүктөлгөн) методдорго да тиешелүү. Полиморфизмди колдонуу практикасы

Интервью суроолору - Java синтаксиси

5. Java тorнде конструктор деген эмне?

Төмөнкү мүнөздөмөлөр жарактуу болуп саналат:
  1. Жаңы an object түзүлгөндө, программа бул үчүн тиешелүү конструкторду колдонот.
  2. Конструктор метод сыяктуу. Анын өзгөчөлүгү кайтаруучу элементи жок (анын ичинде жараксыз) жана анын аты класстын аталышы менен бирдей.
  3. Эгерде эч кандай конструктор ачык жазылбаса, автоматтык түрдө бош конструктор түзүлөт.
  4. Конструкторду жокко чыгарса болот.
  5. Эгер параметрлери бар конструктор түзүлсө, бирок параметрсиз да керек болсо, ал өзүнчө жазылышы керек, анткени ал автоматтык түрдө түзүлбөйт.

6. Объекттен кайсы эки класс тукум кууbyte?

Провокацияларга алданбаңыз, мындай класстар жок: бардык класстар түздөн-түз же ата-бабалар аркылуу Объект классынан мураска алынган!

7. Жергorктүү өзгөрмө деген эмне?

Java иштеп чыгуучусунун маегинде дагы бир популярдуу суроо. Жергorктүү өзгөрмө - бул методдун ичинде аныкталган жана метод аткарылганга чейин бар өзгөрмө. Аткаруу аяктагандан кийин, жергorктүү өзгөрмө өз ишин токтотот. Бул жерде main() методунда helloMessage локалдык өзгөрмөсүн колдонгон программа:
public static void main(String[] args) {
   String helloMessage;
   helloMessage = "Hello, World!";
   System.out.println(helloMessage);
}

8. Instance Variable деген эмне?

Instance Variable класстын ичинде аныкталган өзгөрмө жана ал an object бар учурга чейин бар. Мисал Bee классы болуп саналат, анын эки өзгөрмөлөрү nectarCapacity жана maxNectarCapacity бар:
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();
}
Мындан кээ бир нюанстар келип чыгат:
  • интерфейстин бардык ыкмалары ачык жана абстракттуу;
  • бардык өзгөрмөлөр ачык статикалык акыркы болуп саналат;
  • класстар аларды мурастаbyte (узарат), бирок аларды ишке ашырат (ишке ашырат). Мындан тышкары, сиз каалагандай көп интерфейстерди ишке ашыра аласыз.
  • интерфейсти ишке ашырган класстар интерфейстин бардык ыкмаларын ишке ашырууну камсыз кылышы керек.
Бул сыяктуу:
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");
   }
}
Жана бул эки интерфейсти ишке ашырган класс бар. foo()Белгисиздикти болтурбоо жана codeду компиляциялоо үчүн класстагы методду жокко чыгарышыбыз керек жана биз жөн гана андагы интерфейстердин каалаган Cыкмасын чакыра алабыз - же . Бирок конкреттүү интерфейс ыкмасын кантип тандоо керек же ? Бул үчүн мындай структура бар : foo()ABАВ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синхрондуу жана ошондуктан жип коопсуз;
  • Жиптин коопсуздугу менен иштөө ылдамдыгы көп нерсени каалаbyte.
Мисал:
StringBuffer name = "book";
Топ 50 Java негизги интервью суроолору жана жооптору.  1-6-бөлүкАттын мааниси өзгөрөөрү менен, стектеги маани өзгөрөт: Топ 50 Java негизги интервью суроолору жана жооптору.  1-7-бөлүкStringBuilder Так менен бирдей StringBuffer, болгону ал жип коопсуз эмес. Демек, анын ылдамдыгы StringBuffer.

18. Абстракттуу класс менен интерфейстин ортосунда кандай айырма бар?

Абстракттуу класс:
  • абстракттуу класстардын демейки конструктору бар; бул абстракттуу класстын баласы түзүлгөн сайын аталат;
  • абстракттуу жана абстракттуу эмес ыкмаларды камтыйт. Жалпысынан алганда, ал абстрактуу методдорду камтыбашы мүмкүн, бирок дагы эле абстракттуу класс болушу мүмкүн;
  • абстракттуу класстан тукум кууп өткөн класс абстракттуу методдорду гана ишке ашырышы керек;
  • абстракттуу класс Instance Variable камтышы мүмкүн (№5 суроону караңыз).
Интерфейс:
  • конструктор жок жана инициализациялоо мүмкүн эмес;
  • абстракттуу методдорду гана кошуу керек (демейки ыкмаларды эсепке албаганда);
  • интерфейсти ишке ашыруучу класстар бардык методдорду ишке ашыруусу керек (демейки ыкмаларды эсепке албаганда);
  • интерфейстер туруктууларды гана камтышы мүмкүн.

19. Эмне үчүн массивдеги элементке жетүү O(1)ди алат?

Бул суроо түзмө-түз акыркы маектен алынган. Кийин билдим, бул суроо адам кандай ойдо экенин көрүү үчүн берилет. Бул бorмдин практикалык мааниси аз экени түшүнүктүү: бул чындыкты билүү жетиштүү. Биринчиден, О(1) алгоритмдин операция туруктуу убакытта ишке ашкандагы убакыттын татаалдыгын белгилөө экенин такташыбыз керек . Башкача айтканда, бул белгилөө эң тез аткарылат. Бул суроого жооп берүү үчүн, биз массивдер жөнүндө эмнени биле турганыбызды түшүнүшүбүз керек? Массив түзүү үчүн int, биз төмөнкүлөрдү жазышыбыз керек:
int[] intArray = new int[100];
Бул жазуудан бир нече тыянак чыгарууга болот:
  1. Массивди түзүүдө анын түрү белгилүү болот.Эгер түрү белгилүү болсо, анда массивдин ар бир уячасы кандай өлчөмдө болоору анык болот.
  2. Массив кандай өлчөмдө болоору белгилүү.
Мындан келип чыгат: кайсы уячага жазуу керек экенин түшүнүү үчүн, кайсы эстутум аймагына жазуу керектигин эсептеп алуу керек. Машина үчүн бул жеңorрээк болушу мүмкүн эмес. Машинада бөлүнгөн эс тутумдун башталышы, бир катар элементтер жана бир клетка өлчөмү бар. Ушундан көрүнүп тургандай, жазуу мейкиндиги массивдин башталгыч жерине + анын өлчөмүнө көбөйтүлгөн уячанын өлчөмүнө барабар болот.

ArrayListдеги an objectтерге жетүү үчүн 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 ар кандай болот жана ар кандай кошумча талааларга ээ болушу мүмкүн (же такыр башка). Эмне кылуу керек? Бул жерде суроо баш аламандык жана баш аламандык үчүн коюлган. Биз билебиз, чынында, коллекция an objectтерди сактаbyte, бирок бул an objectтерге шилтемелер гана. Жана бардык шилтемелер бирдей өлчөмгө ээ жана ал белгилүү. Ошентип, бул жерде мейкиндикти эсептөө мурунку суроодогудай эле иштейт.

21. Автобокс жана кутудан чыгаруу

Тарыхый фон: autoboxing жана autounboxing JDK 5тин негизги инновацияларынын бири. Autoboxing – примитивдик типтен тиешелүү орогуч классына автоматтык түрдө өзгөртүү процесси. Auto-unboxing - авто-бокстун так карама-каршысын жасайт - орогуч классын примитивге айлантат. Бирок, эгерде орогучтун мааниси бар болсо null, анда таңгактан чыгаруу учурунда өзгөчө жагдай пайда болотNullPointerException .

Дал келүүчү примитив - орогуч

Примитивдик Каптоочу класс
логикалык логикалык
int бүтүн сан
byte Байт
char Каарман
сүзүү Float
узун Long
кыска Кыска
кош Double

Autopacking пайда болот:

  • орама классына примитивдүү шилтеме ыйгарганда:

    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. Акыркы өзгөрмө башка an objectке кайра дайындалышы мүмкүн эмес.
  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өзгөрмөлүү болсо, методдорду жана өзгөрмөлөрдү колдонуу менен өзгөрмө тиешелүү an objectтин маанисин өзгөртүүгө болот 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?");
}

Жергorктүү акыркы өзгөрмөлөр

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. Жөнөкөй сөз менен айтканда, эч бир класс мындан мурастай алbyte. 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'да финалды кантип жана кайда колдонуу керек

  • кээ бир класс деңгээлиндеги туруктууларды аныктоо үчүн акыркы ачкыч сөздү колдонуу;
  • алардын өзгөртүлүшүн каалабаганыңызда an objectтер үчүн акыркы өзгөрмөлөрдү түзүңүз. Мисалы, биз журналдарды каттоо үчүн колдоно ала турган an objectке мүнөздүү касиеттер;
  • класстын узартылышын каалабасаңыз, аны акыркы деп белгилеңиз;
  • өзгөрүлгүс класс түзүү керек болсо, аны акыркы кылуу керек;
  • эгерде сиз ыкманы ишке ашыруу анын тукумдарында өзгөрбөшүн кааласаңыз, ыкманы катары белгилеңиз final. Бул ишке ашыруу өзгөрбөсүн камсыз кылуу үчүн абдан маанилүү болуп саналат.

23. Өзгөрүүчү өзгөрүлгүс деген эмне?

Өзгөрүүчү

Өзгөрүүчү - түзүлгөндөн кийин абалдары жана өзгөрмөлөрү өзгөртүлүшү мүмкүн болгон an objectтер. Мисалы, 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 түзүлгөндөн кийин абалдары жана өзгөрмөлөрү өзгөрүлбөй турган 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 objectтин өзүн, анын өзгөрмөлөрүн, өзгөрмөлөрдүн өзгөрмөлөрүн ж.б. көчүрүү)
  • реалдуу an objectтерге шилтемелерди эмес, баалуулуктардын көчүрмөлөрүн гана кайтаруу үчүн алгычтардагы өзгөрүлмө 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