CodeGym /Blog Java /Aleatoriu /Top 50 de întrebări și răspunsuri la interviul de angajar...
John Squirrels
Nivel
San Francisco

Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core. Partea 1

Publicat în grup
Salutare tuturor, doamnelor și domnilor, ingineri software! Să vorbim despre întrebările interviului. Despre ce trebuie să te pregătești și ce trebuie să știi. Acesta este un moment minunat pentru a revizui sau a studia aceste puncte pentru prima dată. Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 1 Am ajuns cu o colecție destul de extinsă de întrebări frecvente despre OOP, sintaxa Java, excepții Java, colecții și multithreading, pe care le voi împărți în mai multe părți pentru comoditate. Este greu să acoperiți totul deodată, dar sper că acest material va oferi o bază bună pentru cei care se pregătesc să își găsească primul loc de muncă ca programator. Pentru cea mai bună înțelegere și reținere, vă sfătuiesc să căutați și prin alte surse. Puteți obține o înțelegere mai profundă a unui concept abordându-l din mai multe unghiuri diferite. Important:Vom vorbi doar despre Java înainte de versiunea 8. Toate inovațiile care au venit în versiunile 9, 10, 11, 12 și 13 nu vor fi luate în considerare aici. Orice idei/comentarii despre cum să îmbunătățiți răspunsurile sunt binevenite . Lectură plăcută. Să mergem!

Interviu Java: întrebări despre OOP

1. Care sunt caracteristicile Java?

Răspuns:
  1. Concepte POO:

    1. orientarea obiectelor
    2. moştenire
    3. încapsulare
    4. polimorfism
    5. abstractizare
  2. Multiplatformă: un program Java poate fi rulat pe orice platformă fără nicio modificare. Desigur, acest lucru necesită un JVM instalat (mașină virtuală Java).

  3. Performanță ridicată: compilatorul Just-In-Time (JIT) face posibilă performanța ridicată. Compilatorul JIT convertește bytecode în cod mașină și apoi JVM începe execuția.

  4. Multithreading: JVM-ul creează un fir de execuție numit main thread. Un programator poate crea mai multe fire de execuție derivând din clasa Thread sau implementând interfața Runnable.

2. Ce este moștenirea?

Moștenirea înseamnă că o clasă poate moșteni o altă clasă (folosind cuvântul cheie extins ). Aceasta înseamnă că puteți reutiliza codul din clasa pe care o moșteniți. Clasa existentă este cunoscută ca superclassși clasa nou creată este subclass. Oamenii spun, de asemenea, să folosească termenii părinte și child.

public class Animal {
   private int age;
}

public class Dog extends Animal {

}
unde Animaleste parentși Dogeste child.

3. Ce este încapsularea?

Această întrebare este adesea pusă în interviurile pentru posturi de dezvoltator Java. Încapsularea ascunde implementarea utilizând modificatori de acces, gettere și setari. Acest lucru se face pentru a preveni accesul extern oriunde dezvoltatorii consideră că este necesar. Un exemplu simplu din viața reală este mașina. Nu avem acces direct la funcționarea motorului. Tot ce trebuie să facem este să punem cheia în contact și să pornim motorul. Procesele care au loc sub capotă nu sunt treaba noastră. Mai mult decât atât, dacă ar fi să ne amestecăm în activitatea motorului, ar putea duce la o situație imprevizibilă, posibil deteriorarea mașinii și soldarea cu vătămare corporală. Exact același lucru se întâmplă în programare. Acest lucru este descris bine pe Wikipedia. Există, de asemenea, un articol despre încapsulare pe CodeGym .

4. Ce este polimorfismul?

Polimorfismul este capacitatea unui program de a trata obiecte cu aceeași interfață în același mod, fără informații despre tipul specific al obiectului. După cum se spune, „o interfață – multe implementări”. Cu polimorfismul, puteți combina și utiliza diferite tipuri de obiecte pe baza comportamentelor comune. De exemplu, avem o clasă Animal care are doi descendenți: câine și pisică. Clasa generică Animal are un comportament împărtășit de toți, abilitatea de a scoate un sunet. Folosim capabilități polimorfe atunci când trebuie să adunăm tot ce moștenește clasa Animal și să executăm metoda „a face sunet”. Iată cum arată:

List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Cu alte cuvinte, polimorfismul este de ajutor. Și acest lucru se aplică și metodelor polimorfe (supraîncărcate). Cum se folosește polimorfismul

Întrebări de interviu despre sintaxa Java

5. Ce este un constructor în Java?

Constructorii au următoarele caracteristici:
  1. Când este creat un nou obiect, programul folosește constructorul corespunzător pentru a-l crea.
  2. Un constructor este ca o metodă. Caracteristicile sale distinctive constau în faptul că nu există o valoare de returnare (inclusiv void) și că numele său este același cu numele clasei.
  3. Dacă niciun constructor nu este creat în mod explicit, un constructor gol este creat automat.
  4. Un constructor poate fi suprascris.
  5. Dacă declarați un constructor cu parametri, dar aveți nevoie și de unul fără parametri, atunci trebuie să îl creați separat, deoarece nu va fi creat automat.

6. Care două clase nu moștenesc Object?

Nu vă lăsați păcăliți de întrebările truc - nu există astfel de cursuri. Toate clasele moștenesc clasa Object fie direct, fie prin strămoși!

7. Ce este o variabilă locală?

Aceasta este o altă întrebare populară de interviu pentru dezvoltatorii Java. O variabilă locală este o variabilă care este definită în interiorul unei metode și există atâta timp cât metoda este executată. Imediat ce execuția se termină, variabila locală încetează să mai existe. Iată un program care utilizează o variabilă locală numită helloMessage în metoda main():

public static void main(String[] args) {
   String helloMessage;
   helloMessage = "Hello, World!";
   System.out.println(helloMessage);
}

8. Ce este o variabilă de instanță?

O variabilă de instanță este o variabilă care este declarată în interiorul unei clase. Ea există atâta timp cât există un obiect. De exemplu, avem o clasă Bee, care are două variabile de instanță - nectarLoad și maxNectarLoad:

public class Bee {

   /**
    * Current nectar load
    */
   private double nectarLoad;

   /**
    * Maximum nectar that can the bee can collect.
    */
   private double maxNectarLoad = 20.0;
 
  ...
}

9. Ce sunt modificatorii de acces?

Modificatorii de acces sunt un mecanism de personalizare a accesului la clase, metode și variabile. Există următorii modificatori, listați în ordinea creșterii accesului:
  1. private— Acest modificator de acces este utilizat pe metode, câmpuri și constructori. Accesul este limitat la clasa în care sunt declarați.
  2. package-private (default)— Acesta este nivelul de acces implicit pentru clase. Accesul este limitat la pachetul specific în care este declarată o clasă, o metodă, o variabilă sau un constructor.
  3. protected— Acest modificator de acces oferă același nivel de acces ca și package-privatecu adăugarea de acces pentru clasele care moștenesc o clasă cu modificatorul protected.
  4. public— Acest nivel de acces este folosit și pentru cursuri. Acest nivel de acces înseamnă că există acces complet în întreaga aplicație.
Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 2

10. Ce este anularea metodei?

Ignorăm metodele atunci când o clasă copil dorește să schimbe comportamentul clasei părinte. Dacă trebuie să facem și ceea ce este în metoda părinte, putem folosi super.methodName() în copil, care va executa metoda părinte. Putem adăuga logica noastră suplimentară după aceea. Cerințe care trebuie respectate:
  • semnătura metodei trebuie să fie aceeași
  • valoarea returnată trebuie să fie aceeași

11. Ce sunt semnăturile metodei?

Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 3Semnătura unei metode este combinația dintre numele metodei și argumentele pe care le ia metoda. Semnătura metodei este identificatorul unic al unei metode la supraîncărcarea metodelor.

12. Ce este supraîncărcarea metodei?

Supraîncărcarea metodei este o caracteristică a polimorfismului în care schimbăm semnătura metodei pentru a crea mai multe metode care efectuează aceeași acțiune:
  • acelasi nume
  • argumente diferite
  • pot exista diferite tipuri de returnare
De exemplu, metoda ArrayListclasei add()poate fi supraîncărcată, permițându-ne să adăugăm în moduri diferite în funcție de argumentele de intrare:
  • add(Object o)— Această metodă adaugă pur și simplu un obiect
  • add(int index, Object o)— Această metodă adaugă un obiect la un index specific
  • add(Collection<Object> c)— Această metodă adaugă o listă de obiecte
  • add(int index, Collection<Object> c)— Această metodă adaugă o listă de obiecte pornind de la un index specific.

13. Ce este o interfață?

Java nu acceptă moștenirea multiplă. Pentru a depăși această limitare, au fost adăugate interfețe în forma pe care o cunoaștem și o iubim ;) Multă vreme, interfețele au avut doar metode fără nicio implementare. În contextul acestui răspuns, să vorbim despre ele. De exemplu:


public interface Animal {
   void makeSound();
   void eat();
   void sleep();
}
De aici rezultă câteva detalii:
  • Toate metodele dintr-o interfață sunt publice și abstracte
  • Toate variabilele sunt finale statice publice
  • Clasele nu moștenesc interfețe (adică nu folosim cuvântul cheie extends). În schimb, clasele le implementează (adică folosim cuvântul cheie implements). Mai mult, puteți implementa câte interfețe doriți.
  • Clasele care implementează o interfață trebuie să ofere o implementare a tuturor metodelor care sunt în interfață.
Ca aceasta:

public class Cat implements Animal {
   public void makeSound() {
       // Method implementation
   }

   public void eat() {
       // Implementation
   }

   public void sleep() {
       // Implementation
   }
}

14. Care este o metodă implicită într-o interfață?

Acum să vorbim despre metodele implicite. Pentru ce sunt? Pentru cine sunt? Aceste metode au fost adăugate pentru a servi „ambele mâini”. Despre ce vorbesc? Ei bine, pe de o parte, a fost nevoie să se adauge o nouă funcționalitate: lambdas și Stream API. Pe de altă parte, a fost necesar să se păstreze ceea ce Java este faimos - compatibilitatea cu invers. Pentru a face acest lucru, interfețele aveau nevoie de câteva soluții noi gata făcute. Acesta este modul în care metodele implicite au venit la noi. O metodă implicită este o metodă implementată într-o interfață, marcată cu defaultcuvântul cheie. De exemplu, metoda binecunoscută stream()din Collectioninterfață. Crede-mă, această interfață nu este atât de simplă pe cât pare. Sau, de asemenea, metoda la fel de faimoasă forEach()înIterableinterfata. De asemenea, nu a existat până când au fost adăugate metodele implicite. Apropo, puteți citi despre asta și pe CodeGym aici .

15. Atunci cum moștenim două metode implicite identice?

Răspunsul anterior despre ce este o metodă implicită ridică o altă întrebare. Dacă puteți implementa metode în interfețe, atunci teoretic puteți implementa două interfețe cu aceeași metodă. Cum facem asta? Iată două interfețe diferite cu aceeași metodă:

interface A {
   default void foo() {
       System.out.println("Foo A");
   }
}

interface B {
   default void foo() {
       System.out.println("Foo B");
   }
}
Și avem o clasă care implementează aceste două interfețe. Dar cum alegem o metodă specifică în interfața A sau B? Următorul construct special permite acest lucru A.super.foo():

public class C implements A, B {
   public void fooA() {
       A.super.foo();
   }

   public void fooB() {
       B.super.foo();
   }
}
Astfel, fooA()metoda va folosi foo()metoda implicită a Ainterfeței, în timp ce fooB()metoda va folosi foo()metoda interfeței B.

16. Ce sunt metodele și clasele abstracte?

În Java, abstracteste un cuvânt rezervat. Este folosit pentru a desemna clase și metode abstracte. În primul rând, avem nevoie de definiții. O metodă abstractă este o metodă care este declarată folosind abstractcuvântul cheie fără o implementare într-o clasă abstractă. Adică, aceasta este o metodă ca într-o interfață, dar cu adăugarea unui cuvânt cheie, de exemplu:

public abstract void foo();
O clasă abstractă este o clasă marcată și cu abstractcuvântul cheie:

public abstract class A {

}
O clasă abstractă are mai multe caracteristici:
  • nu puteți crea un obiect dintr-o clasă abstractă
  • poate avea metode abstracte
  • de asemenea, poate să nu aibă metode abstracte
Clasele abstracte sunt necesare pentru abstractizare (scuze pentru tautologie) care are un set de comportamente și stări comune (adică metode și variabile). Viața reală este plină de exemple. Totul în jurul nostru. „Animal”, „Mașină”, „Figură geometrică” și așa mai departe.

17. Care este diferența dintre String, StringBuilder și StringBuffer?

Stringvalorile sunt stocate într-un pool de șiruri constante. De îndată ce un șir este creat, acesta apare în acest pool. Și nu îl puteți șterge. De exemplu:

String name = "book";
Variabila va indica grupul de șiruri constante Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 4Setând variabila nume la o valoare diferită, avem:

name = "pen";
Pool-ul constant de șiruri arată astfel: Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 5Cu alte cuvinte, ambele valori rămân acolo. Buffer de șiruri:
  • Stringvalorile sunt stocate într-o stivă. Dacă o valoare este schimbată, atunci noua valoare o va înlocui pe cea veche.
  • String Buffereste sincronizat și, prin urmare, este sigur pentru fire.
  • Datorită siguranței firului, performanța sa este slabă.
Exemplu:

StringBuffer name = “book”;
Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 6De îndată ce valoarea variabilei nume se schimbă, valoarea din stivă se schimbă: Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 7StringBuilder este exact la fel ca StringBuffer, doar că nu este sigur pentru fire. Drept urmare, este vizibil mai rapid decât StringBuffer.

18. Care este diferența dintre o clasă abstractă și o interfață?

Clasa abstracte:
  • Clasele abstracte au un constructor implicit. Se numește de fiecare dată când este creat un descendent al clasei abstracte.
  • Ele pot include atât metode abstracte, cât și metode non-abstracte. În general, o clasă abstractă nu trebuie să aibă metode abstracte.
  • O clasă care moștenește una abstractă trebuie să implementeze numai metode abstracte.
  • O clasă abstractă poate avea variabile de instanță (vezi Întrebarea #5).
Interfata:
  • O interfață nu are constructor și nu poate fi inițializată.
  • Pot fi adăugate doar metode abstracte (cu excepția metodelor implicite).
  • Clasele care implementează interfața trebuie să implementeze toate metodele (cu excepția metodelor implicite).
  • Interfețele pot avea doar constante.

19. De ce este accesarea unui element dintr-o matrice O(1)?

Această întrebare a fost pusă literalmente în ultimul meu interviu. După cum am aflat mai târziu, scopul acestei întrebări este de a vedea cum gândește o persoană. În mod clar, această cunoaștere are o valoare practică mică. Doar să știi că este suficient. În primul rând, trebuie să clarificăm faptul că O(1) este notația pentru complexitatea de timp a unui algoritm de „timp constant”. Cu alte cuvinte, această desemnare indică cel mai rapid timp de execuție. Pentru a răspunde la această întrebare, trebuie să luăm în considerare ceea ce știm despre matrice. Pentru a crea o intmatrice, trebuie să scriem următoarele:

int[] intArray = new int[100];
Din această sintaxă se pot trage mai multe concluzii:
  1. Când o matrice este declarată, tipul său este cunoscut. Dacă tipul este cunoscut, atunci dimensiunea fiecărei celule din matrice este cunoscută.
  2. Mărimea întregii matrice este cunoscută.
Prin urmare, pentru a înțelege în ce celulă să scriem, trebuie doar să calculăm în ce zonă de memorie să scriem. Pentru un computer, acest lucru este ușor. Calculatorul știe de unde începe memoria alocată, numărul de elemente și dimensiunea fiecărei celule. Toate acestea înseamnă că locul de scris va fi egal cu locul de pornire al matricei + dimensiunea fiecărei celule înmulțită cu index.

Deci, cum ajungem la O(1) când accesăm obiecte dintr-o ArrayList?

Această întrebare urmează imediat celei anterioare. Adevărul este că atunci când lucrăm cu o matrice care conține primitive, știm dinainte (la momentul creării) dimensiunea tipului de element. Dar ce facem dacă avem acest tip de ierarhie de moștenire și Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core.  Partea 1 - 8dorim să creăm o colecție pentru elemente de tip A și să adăugăm diferite implementări (B, C și D):

List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
În această situație, cum calculăm dimensiunea fiecărei celule? La urma urmei, fiecare obiect va fi diferit, eventual cu câmpuri suplimentare diferite. Ce să fac? Aici întrebarea este pusă într-un mod care este menit să vă încurce. Știm că colecția nu stochează direct obiecte. Stochează doar referințe la obiecte. Și toate referințele au aceeași dimensiune și se știe. Ca rezultat, calculăm adresele aici în același mod ca în întrebarea anterioară.

21. Autoboxing și unboxing

Context istoric: autoboxing și unboxing sunt unele dintre principalele inovații din JDK 5. Autoboxing este procesul de conversie automată de la un tip primitiv la o clasă de wrapper corespunzătoare. Unboxing-ul este exact opusul autoboxing-ului. Este procesul de conversie a unei clase wrapper într-o primitivă. Dar dacă valoarea unui ambalaj este null, atunci NullPointerExceptionva fi aruncat în timpul despachetului.

Primitive și învelișurile lor corespunzătoare

Primitiv Clasa Wrapper
boolean boolean
int Întreg
octet octet
char Caracter
pluti Pluti
lung Lung
mic de statura Mic de statura
dubla Dubla

// Autoboxing are loc:

  • atunci când atribuiți o primitivă unei referințe la o clasă wrapper:

    ÎNAINTE de Java 5:

    
    // Manual boxing (the way it was BEFORE Java 5).
    public void boxingBeforeJava5() {
       Boolean booleanBox = new Boolean(true);
       Integer intBox = new Integer(3);
       // And so on for other types
    }
    
    After Java 5:
    // Automatic boxing (the way it became in Java 5).
    public void boxingJava5() {
       Boolean booleanBox = true;
       Integer intBox = 3;
       // And so on for other types
    }
    
  • când o primitivă este transmisă ca argument unei metode care așteaptă un wrapper:

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

// Unboxing are loc:

  • când atribuim o instanță a unei clase wrapper unei variabile primitive:

    
    // 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;
    
  • În timpul operațiilor aritmetice. Operațiunile se aplică numai pentru tipurile primitive, așa că este necesară despachetarea la primitive.

    
    // BEFORE Java 5:
    Integer integerBox1 = new Integer(1);
    Integer integerBox2 = new Integer(2);
    
    // A comparison used to require this:
    integerBox1.intValue() > integerBox2.intValue()
          
    // In Java 5
    integerBox1 > integerBox2
    
  • când treceți o instanță a unei clase wrapper unei metode care ia primitiva corespunzătoare:

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

22. Care este cuvântul cheie final și unde este folosit?

Cuvântul finalcheie poate fi folosit pentru variabile, metode și clase.
  1. Valoarea unei variabile finale nu poate fi modificată după ce este inițializată.
  2. O clasă finală este sterilă :) Nu poate avea copii.
  3. O metodă finală nu poate fi înlocuită de un descendent.
Am acoperit lucrurile de nivel înalt. Acum să ne scufundăm mai adânc.

Variabile finale

Java ne oferă două moduri de a declara o variabilă și de a-i atribui o valoare:
  1. Puteți declara o variabilă și o puteți inițializa mai târziu.
  2. Puteți declara o variabilă și aloca o valoare imediat.
Iată un exemplu care demonstrează aceste utilizări ale variabilelor finale:

public class FinalExample {

   // A static final variable that is immediately initialized:
   final static String FINAL_EXAMPLE_NAME = "I'm likely the final one";

   // A final variable that is not initialized, but will only work if you
   // initialize it 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);

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

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

O variabilă finală poate fi considerată o constantă?

Deoarece nu putem atribui noi valori variabilelor finale, se pare că acestea sunt variabile constante. Dar numai la prima vedere: dacă tipul de date al variabilei este immutable, atunci da, este o constantă. Dar dacă tipul de date este mutable, adică modificabil, atunci va fi posibil să se utilizeze metode și variabile pentru a modifica valoarea obiectului referit de o finalvariabilă. Din această cauză, nu poate fi numită constantă. Următorul exemplu arată că unele variabile finale sunt cu adevărat constante, în timp ce altele nu sunt, deoarece pot fi modificate.

public class FinalExample {

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

   // Mutable final variables
   final List<String> addresses = new ArrayList();
   final StringBuilder finalStringBuilder = new StringBuilder("Constant?");
}

Variabile finale locale

Când o finalvariabilă este creată într-o metodă, se numește variabilă local final:

public class FinalExample {

   public static void main(String[] args) {
       // You can do this
       final int minAgeForDriveCar = 18;

       // Or you can do this, in a for-each loop:
       for (final String arg : args) {
           System.out.println(arg);
       }
   }

}
Putem folosi cuvântul cheie final într-o buclă for îmbunătățită, deoarece o nouă variabilă este creată după fiecare iterație a buclei. Rețineți că acest lucru nu se aplică unei bucle for normale, așa că vom primi o eroare la timp de compilare.

// The final local j variable cannot be assigned
for (final int i = 0; i < args.length; i ++) {
   System.out.println(args[i]);
}

Clasa finală

O clasă declarată ca finalnu poate fi extinsă. Punând-o mai simplu, nicio altă clasă nu o poate moșteni. Un exemplu excelent de finalclasă în JDK este String. Primul pas pentru a crea o clasă imuabilă este să o marchezi ca final, împiedicând astfel extinderea acesteia:

public final class FinalExample {
}

// Compilation error!
class WantsToInheritFinalClass extends FinalExample {
}

Metode finale

Când o metodă este marcată finală, se numește metodă finală (are sens, nu?). O metodă finală nu poate fi suprascrisă într-o clasă copil. De altfel, metodele wait() și notify() ale clasei Object sunt finale, așa că nu avem capacitatea de a le suprascrie.

public class FinalExample {
   public final String generateAddress() {
       return "Some address";
   }
}

class ChildOfFinalExample extends FinalExample {

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

Cum și unde să utilizați final în Java

  • Utilizați cuvântul cheie final pentru a defini unele constante la nivel de clasă;
  • Creați variabile finale pentru obiectele pe care nu doriți să le modificați. De exemplu, proprietăți specifice obiectului pe care le putem folosi în scopuri de înregistrare.
  • Dacă nu doriți ca o clasă să fie prelungită, marcați-o ca finală.
  • Dacă trebuie să creați o clasă imuabilă, trebuie să o faceți finală.
  • Dacă doriți ca implementarea unei metode să nu se schimbe în descendenții ei, atunci marcați metoda ca final. Acest lucru este foarte important pentru a fi sigur că implementarea nu se schimbă.

23. Ce sunt tipurile mutabile și imuabile?

Mutabil

Obiectele mutabile sunt obiecte ale căror stare și variabile pot fi modificate după creare. Exemple de clase mutabile includ StringBuilder și StringBuffer. Exemplu:

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());

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

Imuabil

Obiectele imuabile sunt obiecte ale căror stare și variabile nu pot fi modificate după crearea obiectului. O cheie grozavă pentru un HashMap, nu crezi? :) De exemplu, String, Integer, Double și așa mai departe. Exemplu:

// We'll 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;
   }

   // We remove the setter

   public static void main(String[] args) {

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

       // There is no way to change this field, so it is an immutable object
       // obj.setName("new address");
       // System.out.println(obj.getName());

   }
}
În partea următoare, luăm în considerare întrebările și răspunsurile despre colecții. Profilul meu pe GitHub Top 50 de întrebări și răspunsuri la interviul de angajare pentru Java Core. Partea 2
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION