Wildcards mit oberer Schranke
? extends T für Produzenten
Wildcards mit oberer Schranke ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Generics sind invariant
In Java sind Generics invariant. Eine List<Integer> ist keine List<Number>, obwohl Integer ein Number ist.
Das überrascht Einsteiger, sorgt aber für ein typsicheres Typsystem. Wildcards lockern diese Einschränkung auf sichere Weise.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> ints = List.of(1, 2, 3);
// List<Number> nums = ints; // would NOT compile
System.out.println("List<Integer> is not List<Number>");
System.out.println(ints);
}
}Die Wildcard mit oberer Schranke
? extends T ist eine Wildcard mit oberer Schranke. Das bedeutet: „ein unbekannter Typ, der T oder ein Subtyp von T ist“.
List<? extends Number> kann sich auf eine List<Integer>, eine List<Double> oder eine List<Number> beziehen.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? extends Number> a = List.of(1, 2, 3);
List<? extends Number> b = List.of(1.5, 2.5);
System.out.println(a.get(0));
System.out.println(b.get(0));
}
}Aus einem Producer lesen
Mit ? extends Number können Sie Elemente sicher als Number lesen.
Unabhängig vom tatsächlichen Elementtyp ist garantiert, dass er mindestens ein Number ist. Daher ist das Lesen typsicher.
import java.util.List;
public class Main {
static double sum(List<? extends Number> list) {
double total = 0;
for (Number n : list) total += n.doubleValue();
return total;
}
public static void main(String[] args) {
System.out.println(sum(List.of(1, 2, 3)));
System.out.println(sum(List.of(1.5, 2.5)));
}
}Sie können nicht hineinschreiben
Der entscheidende Punkt ist: Sie können einer ? extends Number-Liste keine Elemente hinzufügen (außer null).
Der Compiler kennt den genauen Elementtyp nicht. Es könnte sich um eine List<Integer> handeln, sodass das Hinzufügen eines Double unsicher wäre.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? extends Number> list = new ArrayList<Integer>();
// list.add(1); // does NOT compile
// list.add(1.5); // does NOT compile
System.out.println("Cannot add to ? extends Number");
System.out.println("size = " + list.size());
}
}Warum das Schreiben verboten ist
Stellen Sie sich vor, es wäre erlaubt. Sie könnten eine List<Integer> als List<? extends Number> übergeben und anschließend ein Double hinzufügen.
Code, der die Liste später als List<Integer> liest, würde eine ClassCastException erhalten. Der Compiler verhindert dies, indem er Schreibzugriffe verbietet.
import java.util.List;
public class Main {
public static void main(String[] args) {
// Conceptual: this is why add is blocked
System.out.println("Writing a Double into a List<Integer> would corrupt it");
System.out.println("so ? extends bans all adds");
}
}Anwendungsfall: Produzent
Verwenden Sie ? extends T, wenn eine Methode Werte nur für Sie produziert, also ausliest.
Eine Methode, die Elemente aus einer Quellsammlung kopiert, ist ein perfektes Beispiel.
import java.util.ArrayList;
import java.util.List;
public class Main {
static List<Number> copyOut(List<? extends Number> source) {
List<Number> dest = new ArrayList<>();
for (Number n : source) dest.add(n);
return dest;
}
public static void main(String[] args) {
System.out.println(copyOut(List.of(1, 2, 3)));
}
}Type-Parameter mit Schranken und Wildcards
Verwechseln Sie <T extends Number> (einen Type-Parameter mit Schranke) nicht mit ? extends Number (einem Wildcard).
- Type-Parameter: Benennt den Typ zur Verwendung in der gesamten Methode.
- Wildcard: Ein unbenannter unbekannter Untertyp, der verwendet wird, wenn Sie ihn nicht benennen müssen.
import java.util.List;
public class Main {
static <T extends Number> T first(List<T> list) { return list.get(0); }
public static void main(String[] args) {
Integer i = first(List.of(10, 20));
System.out.println(i);
}
}Mehrere Schranken
Ein Type-Parameter kann mit & mehrere Schranken haben, zum Beispiel <T extends Number & Comparable<T>>.
Wildcards unterstützen nur eine einzige obere Schranke. Für mehrere Schranken benötigen Sie daher einen benannten Type-Parameter.
import java.util.List;
public class Main {
static <T extends Number & Comparable<T>> T max(List<T> list) {
T best = list.get(0);
for (T t : list) if (t.compareTo(best) > 0) best = t;
return best;
}
public static void main(String[] args) {
System.out.println(max(List.of(3, 9, 1, 7)));
}
}Wildcards mit Collections.max
Das JDK verwendet obere Schranken an vielen Stellen, zum Beispiel beim Aufsummieren oder Durchsuchen einer schreibgeschützten Sammlung.
Hier ermitteln wir das größte Element einer Liste, die als Produzent typisiert ist.
import java.util.List;
public class Main {
static double largest(List<? extends Number> nums) {
double max = Double.NEGATIVE_INFINITY;
for (Number n : nums) max = Math.max(max, n.doubleValue());
return max;
}
public static void main(String[] args) {
System.out.println(largest(List.of(4, 2, 9, 1)));
System.out.println(largest(List.of(0.5, 9.9, 3.3)));
}
}Nur null kann geschrieben werden
Das einzige Element, das Sie einer ? extends T-Sammlung hinzufügen können, ist null, weil null jedem Referenztyp zugewiesen werden kann.
Das ist selten nützlich, erklärt aber, warum add nicht vollständig verboten ist, sondern praktisch schon.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? extends Number> list = new ArrayList<Number>();
// Only null is assignable; demonstrated conceptually
System.out.println("Only null could be added; we avoid that");
System.out.println("size = " + list.size());
}
}Das Auslesen als Object funktioniert immer
Da jeder Typ von Object erbt, können Sie Elemente jeder Wildcard-Liste immer als Object auslesen.
Bei einer oberen Schranke von Number können Sie sie zusätzlich direkt als Number auslesen.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? extends Number> nums = List.of(1, 2.0, 3L);
for (Object o : nums) System.out.println(o.getClass().getSimpleName());
}
}Kurzer Test
Testen Sie Ihr Verständnis der oberen Schranken.
Zusammenfassung
Sie haben Wildcards mit oberer Schranke kennengelernt:
? extends Tbedeutet ein unbekannter Untertyp von T.- Sie können Elemente als T auslesen (ein Produzent).
- Sie können keine Elemente ungleich
nullhinzufügen. - Generics sind invariant, und Wildcards lockern diese Einschränkung auf sichere Weise.
Als Nächstes folgt das Gegenstück: Wildcards mit unterer Schranke.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? extends Number> nums = List.of(1, 2, 3);
System.out.println("Upper bound recap: read " + nums.get(0));
}
}Häufig gestellte Fragen
Ist die Lektion „Wildcards mit oberer Schranke“ kostenlos?
Ja — der vollständige Text von „Wildcards mit oberer Schranke“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Wildcards mit oberer Schranke“?
? extends T für Produzenten Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Wildcards mit oberer Schranke“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Wildcards mit oberer Schranke
- Wildcards mit unterer Schranke
- Das PECS-Prinzip
- Wildcards in APIs