Hallo allemaal, dames en heren, software engineers! Laten we het hebben over interviewvragen. Over waar je je op moet voorbereiden en wat je moet weten. Dit is een goed moment om deze punten voor het eerst te herzien of te bestuderen. Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 1 Ik eindigde met een vrij uitgebreide verzameling veelgestelde vragen over OOP, Java-syntaxis, Java-uitzonderingen, verzamelingen en multithreading, die ik voor het gemak in verschillende delen zal splitsen. Het is moeilijk om alles in één keer te bespreken, maar ik hoop dat dit materiaal een goede basis zal bieden voor degenen die zich voorbereiden op hun eerste baan als programmeur. Voor het beste begrip en behoud raad ik aan om ook andere bronnen te doorzoeken. Je kunt een concept beter begrijpen door het vanuit verschillende invalshoeken te benaderen. Belangrijk:We zullen het alleen hebben over Java vóór versie 8. Alle innovaties die in versie 9, 10, 11, 12 en 13 kwamen, worden hier niet behandeld. Alle ideeën/opmerkingen om de antwoorden te verbeteren zijn welkom . Veel leesplezier. Laten we gaan!

Java-interview: vragen over OOP

1. Wat zijn de kenmerken van Java?

Antwoord:
  1. OOP-concepten:

    1. object oriëntatie
    2. erfenis
    3. inkapseling
    4. polymorfisme
    5. abstractie
  2. Platformoverschrijdend: een Java-programma kan zonder wijzigingen op elk platform worden uitgevoerd. Dit vereist natuurlijk een geïnstalleerde JVM (Java virtual machine).

  3. Hoge prestaties: de Just-In-Time (JIT)-compiler maakt hoge prestaties mogelijk. De JIT-compiler converteert de bytecode naar machinecode en vervolgens begint de JVM met de uitvoering.

  4. Multithreading: De JVM maakt een uitvoeringsthread genaamd de main thread. Een programmeur kan meerdere threads maken door af te leiden van de klasse Thread of door de Runnableinterface te implementeren.

2. Wat is overerving?

Overerving betekent dat een klasse een andere klasse kan erven (met behulp van het sleutelwoord extends ). Dit betekent dat u code kunt hergebruiken van de klasse die u erft. De bestaande klasse staat bekend als de superclassen de nieuw gecreëerde klasse is de subclass. Mensen zeggen ook dat je de termen parent en child.

public class Animal {
   private int age;
}

public class Dog extends Animal {

}
waar Animalis de parenten Dogis de child.

3. Wat is inkapseling?

Deze vraag wordt vaak gesteld in sollicitatiegesprekken voor vacatures voor Java-ontwikkelaars. Inkapseling is het verbergen van de implementatie door toegangsmodifiers, getters en setters te gebruiken. Dit wordt gedaan om externe toegang te voorkomen waar ontwikkelaars denken dat dit nodig is. Een simpel voorbeeld uit het echte leven is de auto. We hebben geen directe toegang tot de werking van de motor. Het enige wat we hoeven te doen is de sleutel in het contact steken en de motor starten. De processen die onder de motorkap plaatsvinden zijn onze zaken niet. Bovendien, als we ons zouden bemoeien met de activiteit van de motor, zou dit kunnen leiden tot een onvoorspelbare situatie, mogelijk met schade aan de auto en lichamelijk letsel tot gevolg. Precies hetzelfde gebeurt bij het programmeren. Dit staat goed beschreven op Wikipedia. Op CodeGym staat ook een artikel over inkapseling .

4. Wat is polymorfisme?

Polymorfisme is het vermogen van een programma om objecten met dezelfde interface op dezelfde manier te behandelen, zonder informatie over het specifieke type van het object. Zoals het gezegde luidt: "één interface - veel implementaties". Met polymorfisme kunt u verschillende soorten objecten combineren en gebruiken op basis van gedeeld gedrag. We hebben bijvoorbeeld een Animal-klasse met twee afstammelingen: Dog en Cat. De generieke Animal-klasse heeft een gedrag dat door iedereen wordt gedeeld, namelijk het vermogen om geluid te maken. We gebruiken polymorfe mogelijkheden wanneer we alles moeten verzamelen dat de klasse Animal erft en de methode "maak geluid" moeten uitvoeren. Zo ziet het eruit:

List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Met andere woorden, polymorfisme is nuttig. En dit geldt ook voor polymorfe (overbelaste) methoden. Hoe polymorfisme te gebruiken

Interviewvragen over Java-syntaxis

5. Wat is een constructor in Java?

Constructeurs hebben de volgende kenmerken:
  1. Wanneer een nieuw object wordt gemaakt, gebruikt het programma de juiste constructor om het te maken.
  2. Een constructor is als een methode. De onderscheidende kenmerken liggen in het feit dat er geen retourwaarde is (inclusief ongeldig) en dat de naam dezelfde is als de naam van de klasse.
  3. Als er geen constructor expliciet wordt gemaakt, wordt er automatisch een lege constructor gemaakt.
  4. Een constructor kan worden overschreven.
  5. Als u een constructor met parameters declareert, maar er ook een zonder parameters nodig heeft, moet u deze apart maken, aangezien deze niet automatisch wordt gemaakt.

6. Welke twee klassen erven Object niet?

Laat u niet misleiden door strikvragen - dergelijke klassen bestaan ​​niet. Alle klassen erven de klasse Object rechtstreeks of via voorouders!

7. Wat is een lokale variabele?

Dit is een andere populaire interviewvraag voor Java-ontwikkelaars. Een lokale variabele is een variabele die binnen een methode is gedefinieerd en bestaat zolang de methode wordt uitgevoerd. Zodra de uitvoering stopt, houdt de lokale variabele op te bestaan. Hier is een programma dat een lokale variabele genaamd helloMessage gebruikt in de main() methode:

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

8. Wat is een instantievariabele?

Een instantievariabele is een variabele die binnen een klasse wordt gedeclareerd. Het bestaat zolang een object bestaat. We hebben bijvoorbeeld een klasse Bee, die twee instantievariabelen heeft: nectarLoad en maxNectarLoad:

public class Bee {

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

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

9. Wat zijn toegangsmodifiers?

Toegangsmodificatoren zijn een mechanisme voor het aanpassen van de toegang tot klassen, methoden en variabelen. De volgende modifiers bestaan, weergegeven in volgorde van toenemende toegang:
  1. private— Deze toegangsmodificator wordt gebruikt op methoden, velden en constructors. De toegang is beperkt tot de klasse waarin ze zijn gedeclareerd.
  2. package-private (default)— Dit is het standaard toegangsniveau voor klassen. Toegang is beperkt tot het specifieke pakket waarin een klasse, methode, variabele of constructor is gedeclareerd.
  3. protected— Deze toegangsmodificator biedt hetzelfde toegangsniveau als package-privatemet de toevoeging van toegang voor klassen die een klasse erven met de protectedmodifier.
  4. public— Dit toegangsniveau wordt ook gebruikt voor lessen. Dit toegangsniveau betekent dat er volledige toegang is tot de hele applicatie.
Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 2

10. Wat is methode-overriding?

We overschrijven methoden wanneer een onderliggende klasse het gedrag van de bovenliggende klasse wil wijzigen. Als we ook moeten doen wat in de parent-methode staat, kunnen we super.methodName() in de child gebruiken, die de parent-methode zal uitvoeren. Daarna kunnen we onze aanvullende logica toevoegen. Vereisten die in acht moeten worden genomen:
  • de handtekening van de methode moet hetzelfde zijn
  • de retourwaarde moet hetzelfde zijn

11. Wat zijn methodehandtekeningen?

Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 3Een methodehandtekening is de combinatie van de naam van de methode en de argumenten die de methode nodig heeft. De methodehandtekening is de unieke identificatie van een methode bij het overbelasten van methoden.

12. Wat is methode-overbelasting?

Methode-overbelasting is een kenmerk van polymorfisme waarbij we de handtekening van de methode wijzigen om meerdere methoden te creëren die dezelfde actie uitvoeren:
  • dezelfde naam
  • verschillende argumenten
  • er kunnen verschillende soorten retourzendingen zijn
ArrayListDe methode van de klasse kan bijvoorbeeld add()overbelast zijn, waardoor we op verschillende manieren kunnen toevoegen, afhankelijk van de invoerargumenten:
  • add(Object o)— Deze methode voegt gewoon een object toe
  • add(int index, Object o)— Deze methode voegt een object toe aan een specifieke index
  • add(Collection<Object> c)— Deze methode voegt een lijst met objecten toe
  • add(int index, Collection<Object> c)— Deze methode voegt een lijst met objecten toe vanaf een specifieke index.

13. Wat is een interface?

Java ondersteunt geen meervoudige overerving. Om deze beperking te overwinnen, werden interfaces toegevoegd in de vorm die we kennen en waar we van houden ;) Lange tijd hadden interfaces alleen methoden zonder enige implementatie. Laten we er in de context van dit antwoord over praten. Bijvoorbeeld:


public interface Animal {
   void makeSound();
   void eat();
   void sleep();
}
Hieruit volgen enkele details:
  • Alle methoden in een interface zijn openbaar en abstract
  • Alle variabelen zijn publiek statisch definitief
  • Klassen erven geen interfaces (dwz we gebruiken het sleutelwoord extends niet). In plaats daarvan implementeren klassen ze (dwz we gebruiken het sleutelwoord implements). Bovendien kunt u zoveel interfaces implementeren als u wilt.
  • Klassen die een interface implementeren, moeten een implementatie bieden van alle methoden die zich in de interface bevinden.
Soortgelijk:

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

   public void eat() {
       // Implementation
   }

   public void sleep() {
       // Implementation
   }
}

14. Wat is een standaardmethode in een interface?

Laten we het nu hebben over standaardmethoden. Waar zijn die voor? Voor wie zijn ze bedoeld? Deze methoden zijn toegevoegd om "beide handen" te dienen. Waar heb ik het over? Wel, aan de ene kant was er behoefte om nieuwe functionaliteit toe te voegen: lambda's en de Stream API. Aan de andere kant was het nodig om vast te houden waar Java om bekend staat: achterwaartse compatibiliteit. Hiervoor hadden interfaces een aantal nieuwe kant-en-klare oplossingen nodig. Dit is hoe standaardmethoden tot ons kwamen. Een standaardmethode is een geïmplementeerde methode in een interface, gemarkeerd met het defaulttrefwoord. Bijvoorbeeld de bekende stream()methode in de Collectioninterface. Geloof me, deze interface is niet zo eenvoudig als het lijkt. Of ook de al even bekende forEach()methode in deIterablekoppel. Het bestond ook niet totdat de standaardmethoden werden toegevoegd. Je kunt er trouwens ook hier over lezen op CodeGym .

15. Hoe erven we dan twee identieke standaardmethoden?

Het vorige antwoord over wat een standaardmethode is, roept een andere vraag op. Als je methoden in interfaces kunt implementeren, dan kun je in theorie twee interfaces met dezelfde methode implementeren. Hoe doen we dat? Hier zijn twee verschillende interfaces met dezelfde methode:

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

interface B {
   default void foo() {
       System.out.println("Foo B");
   }
}
En we hebben een klasse die deze twee interfaces implementeert. Maar hoe kiezen we een specifieke methode in interface A of B? De volgende speciale constructie maakt dit mogelijk: A.super.foo():

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

   public void fooB() {
       B.super.foo();
   }
}
fooA()De methode gebruikt dus de foo()standaardmethode van de Ainterface, terwijl de methode de methode van de interface fooB()gebruikt . foo()B

16. Wat zijn abstracte methoden en klassen?

In Java abstractis dit een gereserveerd woord. Het wordt gebruikt om abstracte klassen en methoden aan te duiden. Ten eerste hebben we definities nodig. Een abstracte methode is een methode die wordt gedeclareerd met behulp van het abstracttrefwoord zonder een implementatie in een abstracte klasse. Dat wil zeggen, dit is een methode zoals in een interface, maar met toevoeging van een trefwoord, bijvoorbeeld:

public abstract void foo();
Een abstracte klasse is een klasse die ook is gemarkeerd met het abstracttrefwoord:

public abstract class A {

}
Een abstracte klasse heeft verschillende kenmerken:
  • je kunt geen object van een abstracte klasse maken
  • het kan abstracte methoden hebben
  • het kan ook geen abstracte methoden hebben
Abstracte klassen zijn nodig voor abstractie (sorry voor de tautologie) die een reeks gemeenschappelijke gedragingen en toestanden heeft (dat wil zeggen methoden en variabelen). Het echte leven zit vol met voorbeelden. Alles om ons heen. "Dier", "Auto", "Geometrische figuur", enzovoort.

17. Wat is het verschil tussen String, StringBuilder en StringBuffer?

Stringwaarden worden opgeslagen in een constante tekenreekspool. Zodra een string is aangemaakt, verschijnt deze in deze pool. En je kunt het niet verwijderen. Bijvoorbeeld:

String name = "book";
De variabele verwijst naar de constante stringpool. Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 4Als we de naamvariabele op een andere waarde zetten, hebben we:

name = "pen";
De pool met constante tekenreeksen ziet er als volgt uit: Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 5Met andere woorden, beide waarden blijven behouden. Tekenreeksbuffer:
  • Stringwaarden worden opgeslagen in een stapel. Als een waarde wordt gewijzigd, vervangt de nieuwe waarde de oude.
  • String Bufferis gesynchroniseerd en is daarom thread-safe.
  • Vanwege draadveiligheid zijn de prestaties slecht.
Voorbeeld:

StringBuffer name = “book”;
Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 6Zodra de waarde van de naamvariabele verandert, verandert de waarde in de stack: Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 7StringBuilder is precies hetzelfde als StringBuffer, alleen is het niet thread-safe. Als gevolg hiervan is het merkbaar sneller dan StringBuffer.

18. Wat is het verschil tussen een abstracte klasse en een interface?

Abstracte klasse:
  • Abstracte klassen hebben een standaardconstructor. Het wordt elke keer aangeroepen als een afstammeling van de abstracte klasse wordt gemaakt.
  • Ze kunnen zowel abstracte methoden als niet-abstracte methoden bevatten. Over het algemeen hoeft een abstracte klasse geen abstracte methoden te hebben.
  • Een klasse die een abstracte erft, moet alleen abstracte methoden implementeren.
  • Een abstracte klasse kan instantievariabelen hebben (zie vraag #5).
Koppel:
  • Een interface heeft geen constructor en kan niet worden geïnitialiseerd.
  • Alleen abstracte methoden kunnen worden toegevoegd (behalve standaardmethoden).
  • Klassen die de interface implementeren, moeten alle methoden implementeren (behalve standaardmethoden).
  • Interfaces kunnen alleen constanten hebben.

19. Waarom is toegang tot een element in een array O(1)?

Deze vraag werd letterlijk gesteld in mijn laatste interview. Zoals ik later leerde, is het doel van deze vraag om te zien hoe een persoon denkt. Het is duidelijk dat deze kennis weinig praktische waarde heeft. Alleen weten dat het genoeg is. Eerst moeten we verduidelijken dat O(1) de notatie is voor de tijdcomplexiteit van een "constante tijd"-algoritme. Met andere woorden, deze aanduiding geeft de snelste uitvoeringstijd aan. Om deze vraag te beantwoorden, moeten we nadenken over wat we weten over arrays. Om een int​​array te maken, moeten we het volgende schrijven:

int[] intArray = new int[100];
Uit deze syntaxis kunnen verschillende conclusies worden getrokken:
  1. Wanneer een array wordt gedeclareerd, is het type bekend. Als het type bekend is, is de grootte van elke cel in de array bekend.
  2. De grootte van de hele array is bekend.
Hieruit volgt dat om te begrijpen naar welke cel we moeten schrijven, we alleen maar hoeven te berekenen naar welk geheugengebied we moeten schrijven. Voor een computer is dit een fluitje van een cent. De computer weet waar het toegewezen geheugen begint, het aantal elementen en de grootte van elke cel. Dit alles betekent dat de plaats om te schrijven gelijk zal zijn aan de startplaats van de array + de grootte van elke cel vermenigvuldigd met de index.

Dus hoe komen we bij O (1) bij toegang tot objecten in een ArrayList?

Deze vraag volgt onmiddellijk op de vorige. De waarheid is dat wanneer we werken met een array die primitieven bevat, we van tevoren (op het moment van creatie) de grootte van het elementtype kennen. Maar wat doen we als we dit soort overervingshiërarchie hebben en Top 50 sollicitatievragen en antwoorden voor Java Core.  Deel 1 - 8we een verzameling willen maken voor elementen van type A en verschillende implementaties willen toevoegen (B, C en D):

List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
Hoe berekenen we in deze situatie de grootte van elke cel? Elk object zal immers anders zijn, eventueel met andere aanvullende velden. Wat moeten we doen? Hier wordt de vraag gesteld op een manier die bedoeld is om u in verwarring te brengen. We weten dat de collectie niet direct objecten opslaat. Het slaat alleen verwijzingen naar objecten op. En alle referenties hebben dezelfde grootte, en het is bekend. Daarom berekenen we hier adressen op dezelfde manier als in de vorige vraag.

21. Autoboxen en uitpakken

Historische achtergrond: autoboxing en unboxing zijn enkele van de belangrijkste innovaties in JDK 5. Autoboxing is het proces van automatische conversie van een primitief type naar een overeenkomstige wrapperklasse. Unboxing is precies het tegenovergestelde van autoboxing. Het is het proces waarbij een wrapper-klasse wordt omgezet in een primitieve. Maar als de waarde van een wrapper is null, NullPointerExceptionwordt er een gegenereerd tijdens het uitpakken.

Primitieven en hun bijbehorende wikkels

Primitief Wrapper klasse
booleaans Booleaans
int Geheel getal
byte Byte
char Karakter
vlot Vlot
lang Lang
kort Kort
dubbele Dubbele

// Autoboxing gebeurt:

  • bij het toewijzen van een primitieve aan een verwijzing naar een wrapperklasse:

    VOOR 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
    }
    
  • wanneer een primitieve als argument wordt doorgegeven aan een methode die een wrapper verwacht:

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

// Unboxing gebeurt:

  • wanneer we een instantie van een wrapper-klasse toewijzen aan een primitieve variabele:

    
    // 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;
    
  • Tijdens rekenkundige bewerkingen. De bewerkingen zijn alleen van toepassing op primitieve typen, dus unboxing naar primitieven is noodzakelijk.

    
    // 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
    
  • bij het doorgeven van een instantie van een wrapper-klasse aan een methode die de overeenkomstige primitieve neemt:

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

22. Wat is het laatste zoekwoord en waar wordt het gebruikt?

Het finalsleutelwoord kan worden gebruikt voor variabelen, methoden en klassen.
  1. De waarde van een laatste variabele kan niet worden gewijzigd nadat deze is geïnitialiseerd.
  2. Een laatste klas is onvruchtbaar :) Het kan geen kinderen krijgen.
  3. Een laatste methode kan niet worden overschreven door een afstammeling.
We hebben de dingen op hoog niveau behandeld. Laten we nu dieper duiken.

Laatste variabelen

Java biedt ons twee manieren om een ​​variabele te declareren en er een waarde aan toe te wijzen:
  1. U kunt een variabele declareren en later initialiseren.
  2. U kunt een variabele declareren en meteen een waarde toekennen.
Hier is een voorbeeld dat dit gebruik van eindvariabelen demonstreert:

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;
   }
}

Kan een laatste variabele als een constante worden beschouwd?

Aangezien we geen nieuwe waarden kunnen toekennen aan eindvariabelen, lijkt het erop dat dit constante variabelen zijn. Maar alleen op het eerste gezicht: als het gegevenstype van de variabele is immutable, dan is het inderdaad een constante. Maar als het gegevenstype mutable, dat wil zeggen veranderlijk is, dan is het mogelijk om methoden en variabelen te gebruiken om de waarde te wijzigen van het object waarnaar wordt verwezen door een finalvariabele. Hierdoor kan het geen constante worden genoemd. Het volgende voorbeeld laat zien dat sommige eindvariabelen echte constanten zijn, terwijl andere dat niet zijn, omdat ze kunnen worden gewijzigd.

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?");
}

Lokale eindvariabelen

Wanneer een finalvariabele binnen een methode wordt gemaakt, wordt deze een local finalvariabele genoemd:

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

}
We kunnen het laatste trefwoord gebruiken in een verbeterde for-lus, omdat er na elke iteratie van de lus een nieuwe variabele wordt gemaakt. Houd er rekening mee dat dit niet van toepassing is op een normale for-lus, dus we krijgen een compileerfout.

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

Laatste klasse

Een klasse die is gedeclareerd als finalkan niet worden uitgebreid. Simpel gezegd, geen enkele andere klasse kan het erven. Een uitstekend voorbeeld van een finalklasse in de JDK is String. De eerste stap bij het maken van een onveranderlijke klasse is deze te markeren als final, waardoor wordt voorkomen dat deze wordt uitgebreid:

public final class FinalExample {
}

// Compilation error!
class WantsToInheritFinalClass extends FinalExample {
}

Laatste methoden

Wanneer een methode als definitief is gemarkeerd, wordt het een definitieve methode genoemd (logisch, toch?). Een laatste methode kan niet worden overschreven in een onderliggende klasse. Overigens zijn de methoden wait() en notification() van de klasse Object definitief, dus we kunnen ze niet overschrijven.

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

class ChildOfFinalExample extends FinalExample {

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

Hoe en waar final te gebruiken in Java

  • Gebruik het laatste trefwoord om enkele constanten op klasseniveau te definiëren;
  • Maak definitieve variabelen voor objecten die u niet wilt wijzigen. Bijvoorbeeld objectspecifieke eigenschappen die we kunnen gebruiken voor logging-doeleinden.
  • Als je niet wilt dat een les wordt verlengd, markeer deze dan als definitief.
  • Als u een onveranderlijke klasse moet maken, moet u deze definitief maken.
  • Als u wilt dat de implementatie van een methode niet verandert in zijn afstammelingen, markeer de methode dan als final. Dit is erg belangrijk om er zeker van te zijn dat de implementatie niet verandert.

23. Wat zijn veranderlijke en onveranderlijke typen?

Veranderlijk

Veranderlijke objecten zijn objecten waarvan de status en variabelen na creatie kunnen worden gewijzigd. Voorbeelden van veranderlijke klassen zijn StringBuilder en StringBuffer. Voorbeeld:

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

Onveranderlijk

Onveranderlijke objecten zijn objecten waarvan de status en variabelen niet kunnen worden gewijzigd nadat het object is gemaakt. Een geweldige sleutel voor een HashMap, vind je niet? :) Bijvoorbeeld String, Integer, Double, enzovoort. Voorbeeld:

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

   }
}
In het volgende deel gaan we in op vragen en antwoorden over collecties. Mijn profiel op GitHub Top 50 sollicitatievragen en antwoorden voor Java Core. Deel 2