CodeGym /Java-Blog /Random-DE /Die 50 wichtigsten Fragen und Antworten zu Vorstellungsge...
John Squirrels
Level 41
San Francisco

Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core. Teil 1

Veröffentlicht in der Gruppe Random-DE
Hallo zusammen, meine Damen und Herren, Software-Ingenieure! Lassen Sie uns über Interviewfragen sprechen. Worauf Sie sich vorbereiten müssen und was Sie wissen müssen. Dies ist ein guter Zeitpunkt, diese Punkte noch einmal durchzugehen oder sich zum ersten Mal mit ihnen zu befassen. Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 1 Am Ende hatte ich eine ziemlich umfangreiche Sammlung häufig gestellter Fragen zu OOP, Java-Syntax, Java-Ausnahmen, Sammlungen und Multithreading, die ich der Einfachheit halber in mehrere Teile aufteilen werde. Es ist schwierig, alles auf einmal abzudecken, aber ich hoffe, dass dieses Material eine gute Grundlage für diejenigen bietet, die sich auf ihren ersten Job als Programmierer vorbereiten. Für ein besseres Verständnis und eine optimale Aufbewahrung empfehle ich, auch andere Quellen zu durchsuchen. Sie können ein Konzept tiefer verstehen, indem Sie es aus verschiedenen Blickwinkeln betrachten. Wichtig:Wir werden nur über Java vor Version 8 sprechen. Alle Neuerungen, die in den Versionen 9, 10, 11, 12 und 13 eingeführt wurden, werden hier nicht berücksichtigt. Alle Ideen/Kommentare zur Verbesserung der Antworten sind willkommen . Viel Spaß beim Lesen. Lass uns gehen!

Java-Interview: Fragen zu OOP

1. Was sind die Merkmale von Java?

Antworten:
  1. OOP-Konzepte:

    1. Objektorientierung
    2. Nachlass
    3. Verkapselung
    4. Polymorphismus
    5. Abstraktion
  2. Plattformübergreifend: Ein Java-Programm kann ohne Änderungen auf jeder Plattform ausgeführt werden. Voraussetzung hierfür ist natürlich eine installierte JVM (Java Virtual Machine).

  3. Hohe Leistung: Der Just-In-Time (JIT)-Compiler ermöglicht eine hohe Leistung. Der JIT-Compiler wandelt den Bytecode in Maschinencode um und dann beginnt die JVM mit der Ausführung.

  4. Multithreading: Die JVM erstellt einen Ausführungsthread namens main thread. Ein Programmierer kann mehrere Threads erstellen, indem er von der Thread-Klasse ableitet oder die RunnableSchnittstelle implementiert.

2. Was ist Vererbung?

Vererbung bedeutet, dass eine Klasse eine andere Klasse erben kann (mithilfe des Schlüsselworts „extends“ ). Das bedeutet, dass Sie Code aus der von Ihnen geerbten Klasse wiederverwenden können. Die vorhandene Klasse heißt „ superclassund die neu erstellte Klasse heißt „ subclass. Man sagt auch, dass man die Begriffe „Elternteil“ und „verwendet“ child.

public class Animal {
   private int age;
}

public class Dog extends Animal {

}
wo Animalist das parentund Dogist das child.

3. Was ist Kapselung?

Diese Frage wird häufig in Vorstellungsgesprächen für Java-Entwicklerpositionen gestellt. Bei der Kapselung wird die Implementierung durch die Verwendung von Zugriffsmodifikatoren, Gettern und Settern ausgeblendet. Dies geschieht, um externe Zugriffe dort zu verhindern, wo Entwickler dies für notwendig halten. Ein einfaches Beispiel aus dem wirklichen Leben ist das Auto. Wir haben keinen direkten Zugriff auf den Betrieb des Motors. Alles, was wir tun müssen, ist, den Schlüssel ins Zündschloss zu stecken und den Motor anzustellen. Die Prozesse, die unter der Haube ablaufen, gehen uns nichts an. Darüber hinaus könnte ein Eingriff in die Motoraktivität zu einer unvorhersehbaren Situation führen, die möglicherweise zu Schäden am Fahrzeug und zu Körperverletzungen führen könnte. Genau das Gleiche passiert beim Programmieren. Dies ist auf Wikipedia gut beschrieben. Es gibt auch einen Artikel über Kapselung auf CodeGym .

4. Was ist Polymorphismus?

Unter Polymorphismus versteht man die Fähigkeit eines Programms, Objekte mit derselben Schnittstelle auf die gleiche Weise zu behandeln, ohne Informationen über den spezifischen Typ des Objekts zu benötigen. Wie das Sprichwort sagt: „Eine Schnittstelle – viele Implementierungen“. Mit Polymorphismus können Sie verschiedene Objekttypen basierend auf gemeinsamen Verhaltensweisen kombinieren und verwenden. Zum Beispiel haben wir eine Animal-Klasse, die zwei Nachkommen hat: Dog und Cat. Die generische Animal-Klasse verfügt über ein Verhalten, das allen gemeinsam ist: die Fähigkeit, einen Ton zu erzeugen. Wir verwenden polymorphe Fähigkeiten, wenn wir alles sammeln müssen, was die Animal-Klasse erbt, und die Methode „make sound“ ausführen müssen. So sieht es aus:

List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Mit anderen Worten: Polymorphismus ist hilfreich. Und das gilt auch für polymorphe (überladene) Methoden. Wie man Polymorphismus verwendet

Interviewfragen zur Java-Syntax

5. Was ist ein Konstruktor in Java?

Konstruktoren haben die folgenden Eigenschaften:
  1. Wenn ein neues Objekt erstellt wird, verwendet das Programm den entsprechenden Konstruktor, um es zu erstellen.
  2. Ein Konstruktor ist wie eine Methode. Seine Besonderheiten liegen darin, dass es keinen Rückgabewert (einschließlich void) gibt und dass sein Name mit dem Namen der Klasse übereinstimmt.
  3. Wenn kein Konstruktor explizit erstellt wird, wird automatisch ein leerer Konstruktor erstellt.
  4. Ein Konstruktor kann überschrieben werden.
  5. Wenn Sie einen Konstruktor mit Parametern deklarieren, aber auch einen ohne Parameter benötigen, müssen Sie ihn separat erstellen, da er nicht automatisch erstellt wird.

6. Welche beiden Klassen erben Object nicht?

Lassen Sie sich nicht von Trickfragen täuschen – solche Kurse gibt es nicht. Alle Klassen erben die Object-Klasse entweder direkt oder über Vorfahren!

7. Was ist eine lokale Variable?

Dies ist eine weitere beliebte Interviewfrage für Java-Entwickler. Eine lokale Variable ist eine Variable, die innerhalb einer Methode definiert ist und solange existiert, wie die Methode ausgeführt wird. Sobald die Ausführung beendet ist, hört die lokale Variable auf zu existieren. Hier ist ein Programm, das eine lokale Variable namens helloMessage in der main()-Methode verwendet:

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

8. Was ist eine Instanzvariable?

Eine Instanzvariable ist eine Variable, die innerhalb einer Klasse deklariert wird. Es existiert, solange ein Objekt existiert. Wir haben zum Beispiel eine Bee-Klasse, die zwei Instanzvariablen hat – nectarLoad und maxNectarLoad:

public class Bee {

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

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

9. Was sind Zugriffsmodifikatoren?

Zugriffsmodifikatoren sind ein Mechanismus zum Anpassen des Zugriffs auf Klassen, Methoden und Variablen. Es gibt die folgenden Modifikatoren, aufgelistet in der Reihenfolge des zunehmenden Zugriffs:
  1. private– Dieser Zugriffsmodifikator wird für Methoden, Felder und Konstruktoren verwendet. Der Zugriff ist auf die Klasse beschränkt, in der sie deklariert sind.
  2. package-private (default)– Dies ist die Standardzugriffsebene für Klassen. Der Zugriff ist auf das spezifische Paket beschränkt, in dem eine Klasse, Methode, Variable oder ein Konstruktor deklariert ist.
  3. protected– Dieser Zugriffsmodifikator bietet die gleiche Zugriffsebene wie package-privatemit dem zusätzlichen Zugriff für Klassen, die eine Klasse mit dem protectedModifikator erben.
  4. public— Diese Zugriffsebene wird auch für Klassen verwendet. Diese Zugriffsebene bedeutet, dass in der gesamten Anwendung vollständiger Zugriff besteht.
Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 2

10. Was ist Methodenüberschreibung?

Wir überschreiben Methoden, wenn eine untergeordnete Klasse das Verhalten ihrer übergeordneten Klasse ändern möchte. Wenn wir auch das tun müssen, was in der übergeordneten Methode enthalten ist, können wir super.methodName() in der untergeordneten Methode verwenden, wodurch die übergeordnete Methode ausgeführt wird. Danach können wir unsere zusätzliche Logik hinzufügen. Zu beachtende Anforderungen:
  • Die Methodensignatur muss identisch sein
  • Der Rückgabewert muss gleich sein

11. Was sind Methodensignaturen?

Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 3Eine Methodensignatur ist die Kombination aus dem Methodennamen und den Argumenten, die die Methode akzeptiert. Die Methodensignatur ist die eindeutige Kennung einer Methode beim Überladen von Methoden.

12. Was ist Methodenüberladung?

Das Überladen von Methoden ist ein Merkmal des Polymorphismus, bei dem wir die Methodensignatur ändern, um mehrere Methoden zu erstellen, die dieselbe Aktion ausführen:
  • der selbe Name
  • verschiedene Argumente
  • Es kann verschiedene Rückgabetypen geben
Beispielsweise kann die Methode ArrayListder Klasse add()überladen werden, sodass wir abhängig von den Eingabeargumenten auf unterschiedliche Weise etwas hinzufügen können:
  • add(Object o)– Diese Methode fügt einfach ein Objekt hinzu
  • add(int index, Object o)– Diese Methode fügt ein Objekt an einem bestimmten Index hinzu
  • add(Collection<Object> c)– Diese Methode fügt eine Liste von Objekten hinzu
  • add(int index, Collection<Object> c)– Diese Methode fügt eine Liste von Objekten hinzu, beginnend mit einem bestimmten Index.

13. Was ist eine Schnittstelle?

Java unterstützt keine Mehrfachvererbung. Um diese Einschränkung zu überwinden, wurden Schnittstellen in der Form hinzugefügt, die wir kennen und lieben ;) Lange Zeit verfügten Schnittstellen nur über Methoden ohne jegliche Implementierung. Lassen Sie uns im Kontext dieser Antwort darüber sprechen. Zum Beispiel:


public interface Animal {
   void makeSound();
   void eat();
   void sleep();
}
Daraus ergeben sich einige Details:
  • Alle Methoden in einer Schnittstelle sind öffentlich und abstrakt
  • Alle Variablen sind öffentliche, statische Endvariablen
  • Klassen erben keine Schnittstellen (dh wir verwenden nicht das Schlüsselwort „extens“). Stattdessen werden sie von Klassen implementiert (dh wir verwenden das Schlüsselwort „implements“). Darüber hinaus können Sie beliebig viele Schnittstellen implementieren.
  • Klassen, die eine Schnittstelle implementieren, müssen eine Implementierung aller in der Schnittstelle enthaltenen Methoden bereitstellen.
So was:

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

   public void eat() {
       // Implementation
   }

   public void sleep() {
       // Implementation
   }
}

14. Was ist eine Standardmethode in einer Schnittstelle?

Lassen Sie uns nun über Standardmethoden sprechen. Wozu dienen sie? Für wen sind die? Diese Methoden wurden hinzugefügt, um „beide Hände“ zu bedienen. Wovon rede ich? Nun, einerseits bestand die Notwendigkeit, neue Funktionen hinzuzufügen: Lambdas und die Stream-API. Andererseits war es notwendig, das beizubehalten, wofür Java berühmt ist – die Abwärtskompatibilität. Dazu benötigte Interfaces einige neue vorgefertigte Lösungen. So kamen Standardmethoden zu uns. Eine Standardmethode ist eine implementierte Methode in einer Schnittstelle, die mit dem defaultSchlüsselwort gekennzeichnet ist. Zum Beispiel die bekannte stream()Methode in der CollectionSchnittstelle. Glauben Sie mir, diese Schnittstelle ist nicht so einfach, wie es scheint. Oder auch die ebenso berühmte forEach()Methode imIterableSchnittstelle. Es existierte auch nicht, bis die Standardmethoden hinzugefügt wurden. Übrigens können Sie hier auch auf CodeGym darüber lesen .

15. Wie erben wir dann zwei identische Standardmethoden?

Die vorherige Antwort darauf, was eine Standardmethode ist, wirft eine andere Frage auf. Wenn Sie Methoden in Schnittstellen implementieren können, können Sie theoretisch zwei Schnittstellen mit derselben Methode implementieren. Wie machen wir das? Hier sind zwei verschiedene Schnittstellen mit derselben Methode:

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

interface B {
   default void foo() {
       System.out.println("Foo B");
   }
}
Und wir haben eine Klasse, die diese beiden Schnittstellen implementiert. Aber wie wählen wir eine bestimmte Methode in Schnittstelle A oder B aus? Das folgende spezielle Konstrukt ermöglicht dies: A.super.foo():

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

   public void fooB() {
       B.super.foo();
   }
}
Daher fooA()verwendet die Methode die Standardmethode foo()der ASchnittstelle, während die Methode die Methode der Schnittstelle fooB()verwendet . foo()B

16. Was sind abstrakte Methoden und Klassen?

In Java abstractist es ein reserviertes Wort. Es wird zur Bezeichnung abstrakter Klassen und Methoden verwendet. Zuerst brauchen wir Definitionen. abstractEine abstrakte Methode ist eine Methode, die mit dem Schlüsselwort ohne Implementierung in einer abstrakten Klasse deklariert wird . Das heißt, es handelt sich um eine Methode wie in einer Schnittstelle, jedoch mit dem Zusatz eines Schlüsselworts, zum Beispiel:

public abstract void foo();
Eine abstrakte Klasse ist eine Klasse, die auch mit dem abstractSchlüsselwort gekennzeichnet ist:

public abstract class A {

}
Eine abstrakte Klasse verfügt über mehrere Funktionen:
  • Sie können kein Objekt einer abstrakten Klasse erstellen
  • es kann abstrakte Methoden haben
  • Möglicherweise gibt es auch keine abstrakten Methoden
Für die Abstraktion werden abstrakte Klassen benötigt (Entschuldigung für die Tautologie), die über eine Reihe gemeinsamer Verhaltensweisen und Zustände (d. h. Methoden und Variablen) verfügen. Das wirkliche Leben ist voller Beispiele. Alles um uns herum. „Tier“, „Auto“, „Geometrische Figur“ und so weiter.

17. Was ist der Unterschied zwischen String, StringBuilder und StringBuffer?

StringWerte werden in einem konstanten String-Pool gespeichert. Sobald ein String erstellt wird, erscheint er in diesem Pool. Und Sie können es nicht löschen. Zum Beispiel:

String name = "book";
Die Variable zeigt auf den konstanten String-Pool. Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 4Wenn wir die Namensvariable auf einen anderen Wert setzen, haben wir:

name = "pen";
Der Konstanten-String-Pool sieht so aus: Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 5Mit anderen Worten, beide Werte bleiben dort. String-Puffer:
  • StringWerte werden in einem Stapel gespeichert. Wenn ein Wert geändert wird, ersetzt der neue Wert den alten.
  • String Bufferist synchronisiert und daher threadsicher.
  • Aufgrund der Thread-Sicherheit ist die Leistung schlecht.
Beispiel:

StringBuffer name = “book”;
Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 6Sobald sich der Wert der Namensvariablen ändert, ändert sich auch der Wert im Stapel: Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 7StringBuilder ist genau das Gleiche wie StringBuffer, nur dass es nicht Thread-sicher ist. Dadurch ist es deutlich schneller als StringBuffer.

18. Was ist der Unterschied zwischen einer abstrakten Klasse und einer Schnittstelle?

Abstrakte Klasse:
  • Abstrakte Klassen haben einen Standardkonstruktor. Es wird jedes Mal aufgerufen, wenn ein Nachkomme der abstrakten Klasse erstellt wird.
  • Sie können sowohl abstrakte als auch nicht abstrakte Methoden umfassen. Im Allgemeinen muss eine abstrakte Klasse keine abstrakten Methoden haben.
  • Eine Klasse, die eine abstrakte Klasse erbt, darf nur abstrakte Methoden implementieren.
  • Eine abstrakte Klasse kann Instanzvariablen haben (siehe Frage Nr. 5).
Schnittstelle:
  • Eine Schnittstelle hat keinen Konstruktor und kann nicht initialisiert werden.
  • Es können nur abstrakte Methoden hinzugefügt werden (außer Standardmethoden).
  • Klassen, die die Schnittstelle implementieren, müssen alle Methoden implementieren (außer Standardmethoden).
  • Schnittstellen können nur Konstanten haben.

19. Warum ist der Zugriff auf ein Element in einem Array O(1)?

Diese Frage wurde mir in meinem letzten Interview wörtlich gestellt. Wie ich später erfuhr, besteht der Zweck dieser Frage darin, herauszufinden, wie eine Person denkt. Offensichtlich hat dieses Wissen wenig praktischen Nutzen. Es genügt, es zu wissen. Zunächst müssen wir klarstellen, dass O(1) eine Notation für die Zeitkomplexität eines Algorithmus mit „konstanter Zeit“ ist. Mit anderen Worten: Diese Bezeichnung gibt die schnellste Ausführungszeit an. Um diese Frage zu beantworten, müssen wir berücksichtigen, was wir über Arrays wissen. Um ein intArray zu erstellen, müssen wir Folgendes schreiben:

int[] intArray = new int[100];
Aus dieser Syntax lassen sich mehrere Schlussfolgerungen ziehen:
  1. Wenn ein Array deklariert wird, ist sein Typ bekannt. Wenn der Typ bekannt ist, ist auch die Größe jeder Zelle im Array bekannt.
  2. Die Größe des gesamten Arrays ist bekannt.
Daraus folgt, dass wir, um zu verstehen, in welche Zelle geschrieben werden soll, lediglich berechnen müssen, in welchen Speicherbereich geschrieben werden soll. Für einen Computer ist das ein Kinderspiel. Der Computer kennt den Beginn des zugewiesenen Speichers, die Anzahl der Elemente und die Größe jeder Zelle. All dies bedeutet, dass die zu schreibende Stelle gleich der Startstelle des Arrays + der Größe jeder Zelle multipliziert mit dem Index ist.

Wie kommen wir also zu O(1), wenn wir auf Objekte in einer ArrayList zugreifen?

Diese Frage folgt unmittelbar auf die vorherige. Die Wahrheit ist, dass wir bei der Arbeit mit einem Array, das Grundelemente enthält, im Voraus (zum Zeitpunkt der Erstellung) die Größe des Elementtyps kennen. Aber was machen wir, wenn wir eine solche Vererbungshierarchie haben und Die 50 wichtigsten Fragen und Antworten zu Vorstellungsgesprächen für Java Core.  Teil 1 - 8eine Sammlung für Elemente vom Typ A erstellen und verschiedene Implementierungen (B, C und D) hinzufügen möchten:

List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
Wie berechnen wir in dieser Situation die Größe jeder Zelle? Schließlich wird jedes Objekt anders sein, möglicherweise mit unterschiedlichen Zusatzfeldern. Was zu tun ist? Hier ist die Frage auf eine Weise gestellt, die Sie verwirren soll. Wir wissen, dass die Sammlung Objekte nicht direkt speichert. Es speichert nur Verweise auf Objekte. Und alle Referenzen haben die gleiche Größe und es ist bekannt. Daher berechnen wir hier Adressen auf die gleiche Weise wie in der vorherigen Frage.

21. Autoboxing und Unboxing

Historischer Hintergrund: Autoboxing und Unboxing sind einige der wichtigsten Neuerungen in JDK 5. Autoboxing ist der Prozess der automatischen Konvertierung von einem primitiven Typ in eine entsprechende Wrapper-Klasse. Unboxing ist das genaue Gegenteil von Autoboxing. Dabei handelt es sich um den Prozess der Konvertierung einer Wrapper-Klasse in ein Grundelement. Wenn der Wert eines Wrappers jedoch ist null, NullPointerExceptionwird beim Unboxing ein geworfen.

Primitive und ihre entsprechenden Wrapper

Primitive Wrapper-Klasse
Boolescher Wert Boolescher Wert
int Ganze Zahl
Byte Byte
verkohlen Charakter
schweben Schweben
lang Lang
kurz Kurz
doppelt Doppelt

// Autoboxing passiert:

  • beim Zuweisen eines Grundelements zu einer Referenz auf eine Wrapper-Klasse:

    VOR 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
    }
    
  • wenn ein Grundelement als Argument an eine Methode übergeben wird, die einen Wrapper erwartet:

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

// Das Auspacken erfolgt:

  • wenn wir einer primitiven Variablen eine Instanz einer Wrapper-Klasse zuweisen:

    
    // 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;
    
  • Bei arithmetischen Operationen. Die Operationen gelten nur für Grundtypen, daher ist ein Auspacken für Grundtypen erforderlich.

    
    // 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
    
  • wenn eine Instanz einer Wrapper-Klasse an eine Methode übergeben wird, die das entsprechende Grundelement annimmt:

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

22. Was ist das letzte Schlüsselwort und wo wird es verwendet?

Das finalSchlüsselwort kann für Variablen, Methoden und Klassen verwendet werden.
  1. Der Wert einer endgültigen Variablen kann nach der Initialisierung nicht mehr geändert werden.
  2. Eine Abschlussklasse ist steril :) Sie kann keine Kinder haben.
  3. Eine finale Methode kann nicht von einem Nachkommen überschrieben werden.
Wir haben die hochrangigen Dinge abgedeckt. Lassen Sie uns nun tiefer eintauchen.

Endgültige Variablen

Java bietet uns zwei Möglichkeiten, eine Variable zu deklarieren und ihr einen Wert zuzuweisen:
  1. Sie können eine Variable deklarieren und später initialisieren.
  2. Sie können eine Variable deklarieren und sofort einen Wert zuweisen.
Hier ist ein Beispiel, das diese Verwendung von Endvariablen demonstriert:

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

Kann eine Endvariable als Konstante betrachtet werden?

Da wir endgültigen Variablen keine neuen Werte zuweisen können, scheint es sich hierbei um konstante Variablen zu handeln. Aber nur auf den ersten Blick: Wenn der Datentyp der Variablen ist immutable, dann ist sie ja eine Konstante. Wenn der Datentyp jedoch mutableveränderbar ist, können Methoden und Variablen verwendet werden, um den Wert des Objekts zu ändern, auf das eine finalVariable verweist. Aus diesem Grund kann es nicht als Konstante bezeichnet werden. Das folgende Beispiel zeigt, dass einige Endvariablen tatsächlich Konstanten sind, andere hingegen nicht, da sie geändert werden können.

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 Endvariablen

Wenn eine finalVariable innerhalb einer Methode erstellt wird, wird sie als local finalVariable bezeichnet:

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

}
Wir können das Schlüsselwort final in einer erweiterten for-Schleife verwenden, da nach jeder Iteration der Schleife eine neue Variable erstellt wird. Beachten Sie, dass dies nicht für eine normale for-Schleife gilt, sodass bei der Kompilierung ein Fehler auftritt.

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

Abschlussklasse

Eine als deklarierte Klasse finalkann nicht erweitert werden. Einfacher ausgedrückt: Keine andere Klasse kann es erben. Ein hervorragendes Beispiel für eine finalKlasse im JDK ist String. Der erste Schritt zum Erstellen einer unveränderlichen Klasse besteht darin, sie als zu markieren und finalso zu verhindern, dass sie erweitert wird:

public final class FinalExample {
}

// Compilation error!
class WantsToInheritFinalClass extends FinalExample {
}

Endgültige Methoden

Wenn eine Methode als final markiert ist, wird sie als finale Methode bezeichnet (macht doch Sinn, oder?). Eine letzte Methode kann in einer untergeordneten Klasse nicht überschrieben werden. Übrigens sind die Methoden „wait()“ und „notify()“ der Object-Klasse endgültig, sodass wir sie nicht überschreiben können.

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

class ChildOfFinalExample extends FinalExample {

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

Wie und wo man final in Java verwendet

  • Verwenden Sie das Schlüsselwort final, um einige Konstanten auf Klassenebene zu definieren.
  • Erstellen Sie endgültige Variablen für Objekte, die nicht geändert werden sollen. Zum Beispiel objektspezifische Eigenschaften, die wir für Protokollierungszwecke verwenden können.
  • Wenn Sie nicht möchten, dass ein Kurs verlängert wird, markieren Sie ihn als endgültig.
  • Wenn Sie eine unveränderliche Klasse erstellen müssen, müssen Sie sie endgültig machen.
  • Wenn Sie möchten, dass sich die Implementierung einer Methode in ihren Nachkommen nicht ändert, markieren Sie die Methode als final. Dies ist sehr wichtig, um sicherzustellen, dass sich die Implementierung nicht ändert.

23. Was sind veränderliche und unveränderliche Typen?

Veränderlich

Veränderbare Objekte sind Objekte, deren Zustand und Variablen nach der Erstellung geändert werden können. Beispiele für veränderliche Klassen sind StringBuilder und StringBuffer. Beispiel:

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

Unveränderlich

Unveränderliche Objekte sind Objekte, deren Status und Variablen nach der Erstellung des Objekts nicht geändert werden können. Ein toller Schlüssel für eine HashMap, finden Sie nicht? :) Zum Beispiel String, Integer, Double und so weiter. Beispiel:

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

   }
}
Im nächsten Teil betrachten wir Fragen und Antworten zu Sammlungen. Mein Profil auf GitHub Top 50 Fragen und Antworten zu Vorstellungsgesprächen für Java Core. Teil 2
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION