Java Generics Konzepte

JavaJavaBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Generics in Java ermöglichen es, flexiblen und wiederverwendbaren Code zu schreiben, indem eine zusätzliche Abstraktionsschicht bereitgestellt wird. Sie ermöglichen es, einen einzelnen Algorithmus für mehrere Objekttypen zu erstellen. Generics bieten Typsicherheit und vermeiden Laufzeitfehler. In diesem Lab werden wir verschiedene Aspekte von Generics in Java verstehen.

Erstellen einer generischen Klasse

Wir können in Java eine generische Klasse mit Hilfe des Diamond-Operators (<>) erstellen. Im folgenden Codeblock werden wir eine generische Klasse namens MyGenericClass erstellen, die beliebige Objekttypen akzeptieren kann. Wir werden auch ein Objekt vom Typ MyGenericClass mit Integer- und Stringtypen als Parameter erstellen.

// ~/project/MyGenericClass.java

class MyGenericClass<T> {
    T field1;

    public MyGenericClass(T field1) {
        this.field1 = field1;
    }

    public T getField1() {
        return field1;
    }
}

public class Main {
    public static void main(String[] args) {
        MyGenericClass<Integer> myIntObj = new MyGenericClass<Integer>(100);
        MyGenericClass<String> myStringObj = new MyGenericClass<String>("Hello World");

        System.out.println(myIntObj.getField1());
        System.out.println(myStringObj.getField1());
    }
}

Um den Code auszuführen, öffnen Sie das Terminal und navigieren Sie zum Verzeichnis ~/project. Kompilieren Sie den Code mit dem folgenden Befehl:

javac MyGenericClass.java

Nach erfolgreicher Kompilierung führen Sie den Code mit dem folgenden Befehl aus:

java Main

Die Ausgabe des Codes wird sein:

100
Hello World

Erstellen einer generischen Methode

Wir können auch in Java eine generische Methode erstellen. Die generische Methode kann mit unterschiedlichen Objekttypen arbeiten. Im folgenden Codeblock werden wir eine generische Methode namens printArray erstellen, die jedes Array beliebigen Typs ausgeben kann.

// ~/project/Main.java

public class Main {
    public static <T> void printArray(T[] array) {
        for (T element : array)
            System.out.println(element);
    }

    public static void main(String[] args) {
        Integer[] intArray = {1, 2, 3, 4, 5};
        Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};
        String[] stringArray = {"Hello", "World"};

        printArray(intArray);
        printArray(doubleArray);
        printArray(stringArray);
    }
}

Um den Code auszuführen, öffnen Sie das Terminal und navigieren Sie zum Verzeichnis ~/project. Kompilieren Sie den Code mit dem folgenden Befehl:

javac Main.java

Nach erfolgreicher Kompilierung führen Sie den Code mit dem folgenden Befehl aus:

java Main

Die Ausgabe des Codes wird sein:

1
2
3
4
5
1.1
2.2
3.3
4.4
Hello
World

Erstellen einer generischen Methode mit Einschränkung

Wir können auch eine generische Methode mit Einschränkung erstellen. Generische Methoden mit Einschränkungen begrenzen den Bereich der akzeptierten Typen. Wir verwenden das Schlüsselwort extends, um die Einschränkung zu setzen. Im folgenden Codeblock werden wir eine generische Methode mit Einschränkung namens printNumbers erstellen, die die Zahlen von Objekten vom Typ Number und seinen Unterklassen ausgeben kann.

// ~/project/Main.java

public class Main {
    public static <T extends Number> void printNumbers(T[] numbers) {
        for (T number : numbers)
            System.out.println(number);
    }

    public static void main(String[] args) {
        Integer[] intNumbers = {1, 2, 3, 4, 5};
        Double[] doubleNumbers = {1.1, 2.2, 3.3, 4.4};

        printNumbers(intNumbers);
        printNumbers(doubleNumbers);
    }
}

Um den Code auszuführen, öffnen Sie das Terminal und navigieren Sie zum Verzeichnis ~/project. Kompilieren Sie den Code mit dem folgenden Befehl:

javac Main.java

Nach erfolgreicher Kompilierung führen Sie den Code mit dem folgenden Befehl aus:

java Main

Die Ausgabe des Codes wird sein:

1
2
3
4
5
1.1
2.2
3.3
4.4

Das Verständnis der Typsicherheit bei Generics

Generics bieten Typsicherheit, indem gewährleistet wird, dass wir nur einen einzigen Objekttyp gleichzeitig verwenden. Im folgenden Codeblock werden wir eine ArrayList von ganzen Zahlen erstellen, ohne ihren Typparameter zu definieren. Es ist eine schlechte Praxis, Generics ohne Typparameter zu verwenden. Der Code wird kompilieren, aber es wird ein Laufzeitfehler zurückgegeben, wenn wir versuchen, Elemente anderer Typen zuzugreifen.

// ~/project/Main.java

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList integerList = new ArrayList();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
        integerList.add("Hello World");

        for (Object element : integerList) {
            System.out.println((Integer)element);
        }
    }
}

Um den Code auszuführen, öffnen Sie das Terminal und navigieren Sie zum Verzeichnis ~/project. Kompilieren Sie den Code mit dem folgenden Befehl:

javac Main.java

Nach erfolgreicher Kompilierung führen Sie den Code mit dem folgenden Befehl aus:

java Main

Die Ausgabe des Codes wird sein:

1
2
3
Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.lang.Integer
    at Main.main(Main.java:13)

Wir erhalten einen Laufzeitfehler, weil die integerList Elemente vom Typ Integer und vom Typ String enthält. Dies liegt daran, dass wir den Typparameter nicht beim Erstellen der integerList definiert haben.

Das Verständnis der Typprägung bei Generics

Java verwendet bei Generics die Typprägung, um sicherzustellen, dass keine zusätzlichen Rechenkosten zur Laufzeit erforderlich sind. Der Compiler ersetzt den Typparameter mit der Klasse Object oder der Oberklasse (im Falle von generischen Methoden mit Einschränkungen) während des Prozesses der Typprägung. Im folgenden Codeblock werden wir sehen, wie Generics mit primitiven Typen zur Compilezeit und Laufzeit funktionieren.

// ~/project/Main.java

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> integerList = new ArrayList<Integer>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);

        int sum = 0;
        for (int i = 0; i < integerList.size(); i++) {
            sum += integerList.get(i);
        }
        System.out.println(sum);
    }
}

Um den Code auszuführen, öffnen Sie das Terminal und navigieren Sie zum Verzeichnis ~/project. Kompilieren Sie den Code mit dem folgenden Befehl:

javac Main.java

Nach erfolgreicher Kompilierung führen Sie den Code mit dem folgenden Befehl aus:

java Main

Die Ausgabe des Codes wird sein:

6

Im obigen Codeblock haben wir versucht, die Elemente der integerList hinzuzufügen. Wie wir wissen, können primitive Typen wie int nicht mit Generics verwendet werden. Aufgrund der Typprägung wird der Typparameter Integer zur Compilezeit durch die Klasse Object ersetzt. Allerdings ermöglicht uns die Autoboxing- und Unboxing-Funktion, die Addition von ganzen Zahlen zur Compilezeit durchzuführen. Zur Laufzeit wurde der Code wie normale Codeausführung ausgeführt, ohne zusätzliche Rechenkosten.

Zusammenfassung

In diesem Lab haben wir uns mit Java Generics beschäftigt. Wir haben die grundlegenden Konzepte rund um generische Klassen, generische Methoden, generische Methoden mit Einschränkungen, Typsicherheit bei Generics und Typprägung bei Generics behandelt. Wir haben auch gesehen, wie man mit Generics flexibles und wiederverwendbares Code schreiben kann. Wir hoffen, dass Ihnen dieses Lab dabei geholfen hat, Generics in Java zu verstehen.