Neben Typen, die als generisch definiert werden können, ist es auch möglich innerhalb von Methoden Typparameter zu verwenden. Eine generische Methode ist eine Methode, die Typparameter verwendet.
Deklaration von generischen Methoden Die folgenden Ableitungsregeln, die für die Deklaration von Methoden gelten, enthalten einen Typparameterabschnitt, der vor der Angabe des Ergebnistyps angeordnet ist: MethodModifiers_opt TypeParamters_opt ResultType Identifier ( FormalParamterList_opt ) Throws_opt MethodBody TypeParamters: < TypeParamterList > TypeParamterList: TypeParamter TypeParamterList , TypeParamter TypeParamter: TypeVariable TypeBound_opt Dieser Typparameterabschnitt wird durch das Nichtterminalsymbol
public <E extends Number & Comparable<E>> E minmax(Vector<E> v, boolean mm) { ... } Der Parameter
Aufruf von generischen Methoden Wird z.B. die Methode minmax(new Vector<Integer>, true) wird durch den Compiler MethodInvocation: Primary . NonWildcardTypeArguments_opt Identifier ( ArgumentList_opt ) Primary: ClassInstanceCreationExpression ClassInstanceCreationExpression: new TypeArguments_opt ClassOrInterfaceType ( ArgumentList_opt ) ClassBody_opt Die letzte Ableitungsregel schafft die Möglichkeit, dass Typargumente explizit einem generischen Konstruktor (siehe Generische Konstruktoren) übergeben werden können. Die Verwendung von Typargumenten bei Methodenaufrufen (siehe 1. Ableitungsregel) verdeutlicht der folgende Ausschnitt aus Listing 3.12: ... public <E> Vector<E> paraVector() { Vector<E> v = new Vector<E>(); return v; } ... Vector<Double> vd = gme.<Double>paraVector(); ... Durch Verwendung von Vector<Double> vd = gme.paraVector(); Eine generische Methode kann also wie eine reguläre Methode aufgerufen werden.
Dies ist möglich, da der Compiler automatisch aus dem Kontext des Methodenaufrufs
die Typargumente folgert. So ist z.B. ersichtlich, dass das Objekt Listing 3.12. /* * GenericMethodExample.java * JDK 5 * */ import java.util.*; public class GenericMethodExample { public <E extends Number & Comparable<E>> E minmax(Vector<E> v, boolean mm) { Iterator<E> iter = v.iterator(); E a = iter.next(); while (iter.hasNext()) { E b = iter.next(); if ((a.compareTo(b) < 0) && (mm == true)) { a = b; } if ((a.compareTo(b) > 0) && (mm == false)) { a = b; } } System.out.println("GenericMethodExample, minmax"); return a; } public <E> Vector<E> paraVector() { Vector<E> v = new Vector<E>(); System.out.println("GenericMethodExample, paraVector"); return v; } public static void main(String[] args) { GenericMethodExample gme = new GenericMethodExample(); Vector<Integer> vi = new Vector<Integer>(); vi.add(new Integer("12")); vi.add(new Integer("4")); vi.add(new Integer("11")); Integer imin = gme.minmax(vi, false); Integer imax = gme.minmax(vi, true); System.out.println("min: " + imin.toString() + ", max: " + imax.toString()); Vector<Double> vd = gme.<Double>paraVector(); vd.add(new Double(Math.random())); vd.add(new Double(Math.random())); vd.add(new Double(Math.random())); Double dmin = gme.minmax(vd, false); Double dmax = gme.minmax(vd, true); System.out.println("min: " + dmin.toString() + ", max: " + dmax.toString()); } } Die Ausgabe des Listings lautet: GenericMethodExample, minmax GenericMethodExample, minmax min: 4, max: 12 GenericMethodExample, paraVector GenericMethodExample, minmax GenericMethodExample, minmax min: 0.28769658374387863, max: 0.8738327953430263 Die Konsolenausgaben "GenericMethodExample, minmax" und "GenericMethodExample, paraVector" wurden in das Beispiel aufgenommen, da sie für Listing 3.15 von Bedeutung sind.
Besitzt eine Klasse einen generischen Konstruktor, können bei der
Instanzierung dieser Klasse dem Konstruktor Typargumente explizit übergeben werden.
Die Angabe dieser Typargumente folgt direkt hinter dem Schlüsselwort public <S extends Number> GenericConstructorExample(S s1, S s2, T t) { ... } Der Konstruktor verwendet die beiden Typparameter GenericConstructorExample gce =
new <Integer> GenericConstructorExample<String>(i1, i2, str); Die Anweisung zur Objekterzeugung legt Listing 3.13. /* * GenericConstructorExample.java * JDK 5 * */ import java.util.*; public class GenericConstructorExample<T> { private T value; public <S extends Number> GenericConstructorExample(S s1, S s2, T t) { Vector<S> v = new Vector<S>(); v.add(s1); v.add(s2); for (int i = 0; i < v.size(); i++) { System.out.println(v.get(i).toString()); } value = t; } public T get() { return value; } public static void main(String[] args) { Integer i1 = new Integer("1"); Integer i2 = new Integer("2"); String str = "test"; GenericConstructorExample gce = new <Integer> GenericConstructorExample<String>(i1, i2, str); Object obj = gce.get(); System.out.println(obj.toString()); } } Die Ausgabe des Beispiels wäre: 1 2 test |
|