1. Alle Klassen erbenObject
Alle Klassen in Java erben implizit die ObjectKlasse.
Wir werden in der Java Core-Quest analysieren, was Vererbung ist und wie sie in Java funktioniert. Zunächst betrachten wir eine einfache Tatsache, die sich daraus ergibt:
Einer Variablen kann ein Objekt einer beliebigen Klasse zugewiesen werden Object. Beispiel:
| Code | Notiz |
|---|---|
|
Die oVariable speichert einen Verweis auf ein ScannerObjekt |
|
Die oVariable speichert einen Verweis auf ein StringObjekt |
|
Die oVariable speichert einen Verweis auf ein IntegerObjekt |
|
Die oVariable speichert einen Verweis auf ein StringObjekt |
Hier endet die gute Nachricht. Der Compiler verfolgt den ursprünglichen Typ des in einer ObjectVariablen gespeicherten Objekts nicht, sodass Sie keine anderen Methoden als die Methoden der Klasse für das gespeicherte Objekt aufrufen können .Object
Wenn Sie die mit dem ursprünglichen Typ des Objekts verknüpften Methoden aufrufen müssen, müssen Sie zunächst einen Verweis darauf in einer Variablen des richtigen Typs speichern und dann die Methoden für diese Variable aufrufen:
| Code | Notiz |
|---|---|
|
Das Programm lässt sich nicht kompilieren. Die ObjectKlasse hat keine nextInt()Methode. |
|
Das wird funktionieren. Hier speichern wir mithilfe eines Typumwandlungsoperators Scanner einen Verweis auf ein Objekt in einer Variablen . Scanner |
ObjectSie können einer Scannervariablen nicht einfach eine Variable zuweisen , selbst wenn die ObjectVariable einen Verweis auf ein ScannerObjekt speichert. Sie können dies jedoch tun, wenn Sie den Typecast-Operator verwenden , den Sie bereits kennen. Dies ist sein allgemeines Erscheinungsbild:
Type name1 = (Type) name2;
Dabei name1ist der Name einer TypeVariablen und name2der Name einer ObjectVariablen, die einen Verweis auf ein TypeObjekt speichert.
Typisierung
Wenn der Typ der Variablen und der Typ des Objekts nicht übereinstimmen, ClassCastExceptionwird ein Fehler ausgelöst. Beispiel:
| Code | Notiz |
|---|---|
|
Zur Laufzeit tritt ein Fehler auf: Hier wird ein Fehler ausgelöst ClassCastException |
In Java gibt es eine Möglichkeit, diesen Fehler zu vermeiden: Wir überprüfen dazu den Typ des in einer Variablen gespeicherten Objekts :
name instanceof Type
Der instanceofOperator prüft, ob die nameVariable ein Objekt ist Type.
Lassen Sie uns als Beispiel eine Zeichenfolge in einem Array verschiedener Objekte finden:
| Code | Notiz |
|---|---|
|
Durch Autoboxing werden diese Werte jeweils in Integer, Stringund umgewandelt Double. Schleife über das Array von Objekten. Wenn es sich bei dem Objekt um ein Objekt handelt, Stringspeichern Sie es in einer StringVariablen . Zeigen Sie die Variable auf dem Bildschirm an. |
2. Warum Generika auftauchten – Sammlungen
Kehren wir zu den Sammlungen zurück.
Sobald Java-Entwickler die ArrayListKlasse erstellt hatten, wollten sie sie universell machen, damit sie jede Art von Objekt speichern kann. Also verwendeten sie ein Array von Objects, um die Elemente zu speichern.
Die Stärke dieses Ansatzes besteht darin, dass Sie der Sammlung ein Objekt beliebigen Typs hinzufügen können.
Natürlich gibt es mehrere Schwächen.
Nachteil 1.
Beim Abrufen von Elementen aus einer Sammlung war es immer notwendig, einen Typkonvertierungsoperator zu schreiben:
| Code | Notiz |
|---|---|
|
Erstellen Sie eine Sammlung, um Verweise auf ObjectObjekte zu speichern . Füllen Sie die Sammlung mit Zahlen 10, 20, ... 100; Summieren Sie die Elemente der Sammlung. Typecasting ist erforderlich |
Nachteil 2.
Es gab keine Garantie dafür, dass eine Sammlung einen bestimmten Elementtyp enthält
| Code | Notiz |
|---|---|
|
Erstellen Sie eine Sammlung, um Verweise auf ObjectObjekte zu speichern. Wir füllen die Sammlung mit Zahlen, die als DoubleObjekte dargestellt werden: 0.0, 2.5, 5.0, ... Summieren Sie die Elemente der Sammlung . Es wird ein Fehler angezeigt: a Doublekann nicht in an umgewandelt werdenInteger |
Daten können überall in die Sammlung aufgenommen werden:
- in einer anderen Methode
- in einem anderen Programm
- aus einer Datei
- über das Netzwerk
Nachteil 3.
Die Daten in der Sammlung können versehentlich geändert werden.
Sie können eine mit Ihren Daten gefüllte Sammlung an eine Methode übergeben. Diese von einem anderen Programmierer geschriebene Methode fügt ihre Daten Ihrer Sammlung hinzu.
Aus dem Namen der Sammlung geht nicht eindeutig hervor, welche Datentypen darin gespeichert werden können. Und selbst wenn Sie Ihrer Variablen einen eindeutigen Namen geben, kann ein Verweis darauf an ein Dutzend Methoden übergeben werden, und diese Methoden wissen definitiv nichts über den ursprünglichen Namen der Variablen.
3. Generika

In Java werden all diese Probleme durch diese coole Sache namens Generics beseitigt.
In Java bedeutet Generics die Möglichkeit, Typparameter zu Typen hinzuzufügen. Das Ergebnis ist ein komplexer zusammengesetzter Typ. Die allgemeine Ansicht eines solchen zusammengesetzten Typs ist folgende:
ClassName<TypeParameter>
Dies ist eine generische Klasse. Und es kann überall dort eingesetzt werden, wo Sie normalerweise Klassen verwenden.
| Code | Beschreibung |
|---|---|
|
Variablen erstellen |
|
Objekte erstellen |
|
Arrays erstellen |
IntegerIn einer solchen Sammlung können nur Variablen gespeichert werden:
| Code | Beschreibung |
|---|---|
|
ArrayListSammlung mit IntegerElementen Das ist erlaubt Und das wird auch funktionieren
Autoboxen
Dies ist jedoch nicht zulässig: Kompilierungsfehler |
In der Quest „Java-Sammlungen“ erfahren Sie, wie Sie Ihre eigenen Klassen mit Typparametern erstellen. Zunächst schauen wir uns an, wie man sie verwendet und wie sie funktionieren.
4. Wie Generika funktionieren
Eigentlich sind Generika furchtbar primitiv.
Der Compiler ersetzt einfach generische Typen durch gewöhnliche Typen. Wenn jedoch Methoden eines generischen Typs verwendet werden, fügt der Compiler einen Typecast-Operator hinzu, um Parameter in die Typparameter umzuwandeln:
| Code | Was der Compiler macht |
|---|---|
|
|
|
|
|
|
|
|
Angenommen, wir haben eine Methode, die die Zahlen in einer Sammlung von ganzen Zahlen summiert:
| Code | Was der Compiler macht |
|---|---|
|
|
Mit anderen Worten, Generika sind eine Art syntaktischer Zucker, genau wie Autoboxing, aber noch ein bisschen mehr. Beim Autoboxing fügt der Compiler Methoden zum Konvertieren von an intin an Integerund umgekehrt hinzu, und für Generika fügt er Typumwandlungsoperatoren hinzu.
Nachdem der Compiler Ihre generischen Klassen mit Typparametern kompiliert hat, werden sie einfach in gewöhnliche Klassen und Typumwandlungsoperatoren konvertiert. Informationen über die Typargumente, die an Variablen generischer Typen übergeben werden, gehen verloren. Dieser Effekt wird auch als Typlöschung bezeichnet .
Manchmal benötigen Programmierer, die generische Klassen (Klassen mit Typparametern) schreiben, wirklich Informationen über die als Argumente übergebenen Typen. In der Quest „Java-Sammlungen“ erfahren Sie, wie Sie damit umgehen und was es mit sich bringt.
5. Ein paar Fakten über Generika
Hier sind einige weitere interessante Fakten über Generika.
Klassen können mehrere Typparameter haben. Es sieht ungefähr so aus:
ClassName<TypeParameter1, TypeParameter2, TypeParameter3>
Eigentlich ist das nicht wirklich überraschend. Überall dort, wo der Compiler einen Operator zur Umwandlung in einen Typ hinzufügen kann, kann er mehrere Typumwandlungsoperatoren hinzufügen.
Beispiele:
| Code | Notiz |
|---|---|
|
Der puterste Parameter der Methode ist ein Integerund der zweite ist einString |
Als Parameter können auch generische Typen verwendet werden . Es sieht ungefähr so aus:
ClassName<TypeParameter<TypeParameterParameter>>
Angenommen, wir möchten eine Liste erstellen, die Listen mit Zeichenfolgen speichert. In diesem Fall erhalten wir etwa Folgendes:
// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");
// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");
// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);
Generische Typen (Typen mit Typparametern) können auch als Array-Typen verwendet werden. Es sieht ungefähr so aus:
ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];
Hier passiert nichts Magisches: Die spitzen Klammern geben lediglich den Typnamen an:
| Code | Nicht-generisches Gegenstück |
|---|---|
|
|
|
|
|
|
GO TO FULL VERSION