Lower bounded wildcards
? super T til konsumenter
Lower bounded wildcards er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.
Jokertegnet med nedre grænse
? super T er et jokertegn med nedre grænse. Det betyder "en ukendt type, der er T eller en supertype til T".
List<? super Integer> kan referere til 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);
}
}Skrivning til en forbruger
Med ? super Integer kan du sikkert tilføje enhver Integer (eller undertype af Integer).
Uanset den faktiske listetype er den mindst en liste af en supertype til Integer, så en Integer passer altid.
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 giver Object
Ulempen er, at compileren kun ved, at elementerne fra en liste med ? super T er en ukendt supertype til T, når du læser fra den.
Den eneste sikre type ved læsning er 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);
}
}Hvorfor læsning er begrænset
En List<? super Integer> kan i virkeligheden være en List<Object>, der indeholder Strings.
En læsning kan derfor returnere et vilkårligt Object. Compileren kan ikke love, at det er en Integer, så læsninger giver kun 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());
}
}Brug af forbruger
Brug ? super T, når en metode kun forbruger (skriver) værdier.
En metode, der udfylder en destinationssamling, er det klassiske tilfælde.
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);
}
}Undertyper kan også tilføjes
Med ? super Number kan du tilføje enhver Number eller dens undertyper: Integer, Double og Long.
Den nedre grænse garanterer, at listen mindst accepterer Number, så alle undertyper passer.
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);
}
}Stilarten i Collections.addAll
JDK'et bruger nedre grænser til modtagere. Et eksempel er en generisk metode, der indsætter elementer 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
Et praktisk eksempel er, at Comparator<? super T> lader en sorteringsmetode acceptere en sammenligner, der er skrevet til en supertype.
En sammenligner, der kan sammenligne alle Object-værdier ved hjælp af toString, kan sortere en liste 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 og extends er spejlbilleder
De to jokertegn er modsætninger:
? extends T: læs T, men skriv ikke. En producent.? super T: skriv T, men læs kun Object. En forbruger.
Denne symmetri er kernen i PECS-reglen, som du lærer om nu.
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);
}
}Kopiering mellem grænser
En kopimetode viser begge jokertegn på én gang: læs fra ? extends T, og skriv til ? 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);
}
}Hvornår du ikke skal bruge et jokertegn
Hvis en metode både læser og skriver T, skal du ikke bruge et jokertegn. Brug en præcis type eller en navngiven typeparameter.
Jokertegn findes netop til tilfælde, hvor der kun læses eller kun skrives.
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);
}
}Hurtigt tjek
Afprøv din forståelse af nedre grænser.
Opsamling
Du har lært om jokertegn med nedre grænser:
? super Tbetyder en ukendt supertype til T.- Du kan skrive T og dens undertyper (en forbruger).
- Læsninger returnerer kun Object.
- Det er det præcise spejlbillede af
? extends T.
Næste emne er reglen, der forbinder dem begge: 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 Java med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 104
- Lektioner
- 374
Ofte stillede spørgsmål
Er lektionen “Lower bounded wildcards” gratis?
Ja — hele teksten til “Lower bounded wildcards” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Lower bounded wildcards”?
? super T til konsumenter Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Java Academy?
Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Lower bounded wildcards”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Java Academy-lektion?
Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Upper bounded wildcards
- Lower bounded wildcards
- PECS-princippet
- Wildcards i API'er