Undre begränsade wildcards
? super T för konsumenter.
Undre begränsade wildcards är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.
Wildcard med nedre begränsning
? super T är ett wildcard med nedre begränsning. Det betyder "någon okänd typ som är T eller en supertyp till T".
List<? super Integer> kan hänvisa till en List<Integer>, en List<Number> eller en List<Object>.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> a = new ArrayList<Number>();
List<? super Integer> b = new ArrayList<Object>();
a.add(1);
b.add(2);
System.out.println(a + " " + b);
}
}Skriva till en konsument
Med ? super Integer kan du säkert lägga till valfri Integer (eller subtyp av Integer).
Oavsett listans faktiska typ är den åtminstone en lista av någon supertyp till Integer, så en Integer passar alltid.
import java.util.ArrayList;
import java.util.List;
public class Main {
static void addNumbers(List<? super Integer> dest) {
for (int i = 1; i <= 3; i++) dest.add(i);
}
public static void main(String[] args) {
List<Number> nums = new ArrayList<>();
addNumbers(nums);
System.out.println(nums);
}
}Läsning ger Object
Nackdelen är att kompilatorn, när du läser från en lista av typen ? super T, bara vet att elementen är någon okänd supertyp till T.
Den enda säkra typen vid läsning är Object.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> list = new ArrayList<Number>();
list.add(10);
Object o = list.get(0); // only Object is guaranteed
// Integer i = list.get(0); // would NOT compile
System.out.println(o);
}
}Varför läsning är begränsad
En List<? super Integer> kan i själva verket vara en List<Object> som innehåller Strings.
En läsning kan därför returnera vilket Object som helst. Kompilatorn kan inte garantera en Integer, så läsningar ger bara Object.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Object> raw = new ArrayList<>();
raw.add("a string");
List<? super Integer> view = raw; // legal: Object is a supertype of Integer
view.add(5);
System.out.println(view.get(0).getClass().getSimpleName());
}
}Användningsfall för konsument
Använd ? super T när en metod bara konsumerar (skriver in) värden.
En metod som fyller på en destinationssamling är det klassiska fallet.
import java.util.ArrayList;
import java.util.List;
public class Main {
static void fill(List<? super String> dest, int count) {
for (int i = 0; i < count; i++) dest.add("item" + i);
}
public static void main(String[] args) {
List<Object> objs = new ArrayList<>();
fill(objs, 3);
System.out.println(objs);
}
}Det fungerar även att lägga till subtyper
Med ? super Number kan du lägga till valfri Number eller dess subtyper: Integer, Double och Long.
Den nedre begränsningen garanterar att listan accepterar åtminstone Number, så alla subtyper passar.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Number> list = new ArrayList<Object>();
list.add(1); // Integer
list.add(2.5); // Double
list.add(3L); // Long
System.out.println(list);
}
}Stil enligt Collections.addAll
JDK använder nedre begränsningar för mottagare. Ett exempel är en generisk metod som lägger till element i en destination.
import java.util.ArrayList;
import java.util.List;
public class Main {
@SafeVarargs
static <T> void addAll(List<? super T> dest, T... items) {
for (T item : items) dest.add(item);
}
public static void main(String[] args) {
List<Object> sink = new ArrayList<>();
addAll(sink, "a", "b", "c");
System.out.println(sink);
}
}Comparator med super
Ett användningsfall från verkligheten: Comparator<? super T> gör att en sortering kan acceptera en comparator som är skriven för en supertyp.
En comparator som jämför valfria Object-värden med hjälp av toString kan sortera en lista med Strings.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
Comparator<Object> byString = Comparator.comparing(Object::toString);
List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
names.sort(byString); // List<String>.sort accepts Comparator<? super String>
System.out.println(names);
}
}super och extends är spegelbilder
De två wildcardsen är varandras motsatser:
? extends T: läs T, skriv inte. En producent.? super T: skriv T, läs bara Object. En konsument.
Denna symmetri är kärnan i PECS-regeln som du får lära dig härnäst.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> consumer = new ArrayList<Number>();
consumer.add(1);
System.out.println("consumer can write: " + consumer);
}
}Kopiera mellan begränsningar
En kopieringsmetod visar båda wildcardsen samtidigt: läs från ? extends T och skriv till ? super T.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> void copy(List<? extends T> src, List<? super T> dest) {
for (T t : src) dest.add(t);
}
public static void main(String[] args) {
List<Integer> src = List.of(1, 2, 3);
List<Number> dest = new ArrayList<>();
copy(src, dest);
System.out.println(dest);
}
}När du inte ska använda ett wildcard
Om en metod både läser och skriver T ska du inte använda ett wildcard. Använd en exakt typ eller en namngiven typparameter.
Wildcards finns specifikt för fall där du bara läser eller bara skriver.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> void swapFirstTwo(List<T> list) {
T tmp = list.get(0);
list.set(0, list.get(1));
list.set(1, tmp);
}
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of("a", "b"));
swapFirstTwo(list);
System.out.println(list);
}
}Snabbkontroll
Testa din förståelse av nedre begränsningar.
Sammanfattning
Du har lärt dig wildcards med nedre begränsning:
? super Tbetyder en okänd supertyp till T.- Du kan skriva T och dess subtyper (en konsument).
- Läsningar returnerar bara Object.
- Det är spegelbilden av
? extends T.
Nästa steg är regeln som knyter ihop dem: PECS.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> list = new ArrayList<Number>();
list.add(42);
System.out.println("Lower bound recap: " + list);
}
}Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 104
- Lektioner
- 374
Vanliga frågor
Är lektionen ”Undre begränsade wildcards” gratis?
Ja – hela texten till ”Undre begränsade wildcards” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Undre begränsade wildcards”?
? super T för konsumenter. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Java Academy?
Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Undre begränsade wildcards”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Java Academy-lektionen?
Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Övre begränsade wildcards
- Undre begränsade wildcards
- PECS-principen
- Wildcards i API:er