Java - Generika
Es wäre schön, wenn wir eine einzelne Sortiermethode schreiben könnten, die die Elemente in einem Integer-Array, einem String-Array oder einem Array eines beliebigen Typs, der eine Sortierung unterstützt, sortieren könnte.
Java Generisch Methoden und generische Klassen ermöglichen es Programmierern, mit einer einzigen Methodendeklaration einen Satz verwandter Methoden bzw. mit einer einzigen Klassendeklaration einen Satz verwandter Typen zu spezifizieren.
Generics bieten auch Typsicherheit zur Kompilierzeit, die es Programmierern ermöglicht, ungültige Typen zur Kompilierzeit abzufangen.
Unter Verwendung des generischen Java-Konzepts könnten wir eine generische Methode zum Sortieren eines Arrays von Objekten schreiben und dann die generische Methode mit Integer-Arrays, Double-Arrays, String-Arrays usw. aufrufen, um die Array-Elemente zu sortieren.
Generische Methoden
Sie können eine einzige generische Methodendeklaration schreiben, die mit Argumenten verschiedener Typen aufgerufen werden kann. Basierend auf den Typen der an die generische Methode übergebenen Argumente behandelt der Compiler jeden Methodenaufruf entsprechend. Es folgen die Regeln zum Definieren generischer Methoden −
-
Alle generischen Methodendeklarationen haben einen durch spitze Klammern (
) begrenzten Typparameterabschnitt, der dem Rückgabetyp der Methode vorangeht ( im nächsten Beispiel). -
Jeder Typparameterabschnitt enthält einen oder mehrere durch Kommas getrennte Typparameter. Ein Typparameter, auch Typvariable genannt, ist ein Bezeichner, der einen generischen Typnamen angibt.
-
Die Typparameter können verwendet werden, um den Rückgabetyp zu deklarieren und als Platzhalter für die Typen der an die generische Methode übergebenen Argumente zu fungieren, die als tatsächliche Typargumente bekannt sind.
-
Der Körper einer generischen Methode wird wie der einer anderen Methode deklariert. Beachten Sie, dass Typparameter nur Referenztypen darstellen können, keine primitiven Typen (wie int, double und char).
Beispiel
Das folgende Beispiel zeigt, wie wir ein Array unterschiedlichen Typs mit einer einzigen generischen Methode drucken können −
Live-Demopublic class GenericMethodTest { // generic method printArray public static < E > void printArray( E[] inputArray ) { // Display array elements for(E element : inputArray) { System.out.printf("%s ", element); } System.out.println(); } public static void main(String args[]) { // Create arrays of Integer, Double and Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println("Array integerArray contains:"); printArray(intArray); // pass an Integer array System.out.println("\nArray doubleArray contains:"); printArray(doubleArray); // pass a Double array System.out.println("\nArray characterArray contains:"); printArray(charArray); // pass a Character array } }
Dies wird das folgende Ergebnis erzeugen −
Ausgabe
Array integerArray contains: 1 2 3 4 5 Array doubleArray contains: 1.1 2.2 3.3 4.4 Array characterArray contains: H E L L O
Begrenzte Typparameter
Es kann vorkommen, dass Sie die Arten von Typen einschränken möchten, die an einen Typparameter übergeben werden dürfen. Beispielsweise möchte eine Methode, die mit Zahlen arbeitet, möglicherweise nur Instanzen von Number oder seinen Unterklassen akzeptieren. Dafür sind begrenzte Typparameter da.
Um einen begrenzten Typparameter zu deklarieren, listen Sie den Namen des Typparameters auf, gefolgt vom Schlüsselwort extend, gefolgt von seiner Obergrenze.
Beispiel
Das folgende Beispiel zeigt, wie „extends“ allgemein verwendet wird, um entweder „extends“ (wie in Klassen) oder „implementiert“ (wie in Interfaces) zu bedeuten. Dieses Beispiel ist eine generische Methode, um das größte von drei vergleichbaren Objekten zurückzugeben −
Live-Demopublic class MaximumTest { // determines the largest of three Comparable objects public static <T extends Comparable<T>> T maximum(T x, T y, T z) { T max = x; // assume x is initially the largest if(y.compareTo(max) > 0) { max = y; // y is the largest so far } if(z.compareTo(max) > 0) { max = z; // z is the largest now } return max; // returns the largest object } public static void main(String args[]) { System.out.printf("Max of %d, %d and %d is %d\n\n", 3, 4, 5, maximum( 3, 4, 5 )); System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n", 6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 )); System.out.printf("Max of %s, %s and %s is %s\n","pear", "apple", "orange", maximum("pear", "apple", "orange")); } }
Dies wird das folgende Ergebnis erzeugen −
Ausgabe
Max of 3, 4 and 5 is 5 Max of 6.6,8.8 and 7.7 is 8.8 Max of pear, apple and orange is pear
Generische Klassen
Eine generische Klassendeklaration sieht aus wie eine nicht generische Klassendeklaration, außer dass auf den Klassennamen ein Typparameterabschnitt folgt.
Wie bei generischen Methoden kann der Typparameterabschnitt einer generischen Klasse einen oder mehrere durch Kommas getrennte Typparameter enthalten. Diese Klassen werden als parametrisierte Klassen oder parametrisierte Typen bezeichnet, da sie einen oder mehrere Parameter akzeptieren.
Beispiel
Das folgende Beispiel zeigt, wie wir eine generische Klasse definieren können −
Live-Demopublic class Box<T> { private T t; public void add(T t) { this.t = t; } public T get() { return t; } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); Box<String> stringBox = new Box<String>(); integerBox.add(new Integer(10)); stringBox.add(new String("Hello World")); System.out.printf("Integer Value :%d\n\n", integerBox.get()); System.out.printf("String Value :%s\n", stringBox.get()); } }
Dies wird das folgende Ergebnis erzeugen −
Ausgabe
Integer Value :10 String Value :Hello World
Java