Curingas com limite inferior
? super T para consumidores.
Curingas com limite inferior é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O curinga com limite inferior
? super T é um curinga com limite inferior. Isso significa "algum tipo desconhecido que é T ou um supertipo de T".
List<? super Integer> pode fazer referência a uma List<Integer>, a uma List<Number> ou a uma 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);
}
}Escrevendo em um consumidor
Com ? super Integer, você pode adicionar com segurança qualquer valor inteiro (ou de um subtipo de inteiro).
Qualquer que seja o tipo real da lista, ela é pelo menos uma lista de algum supertipo de inteiro; portanto, um valor inteiro sempre será aceito.
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);
}
}A leitura fornece Object
A desvantagem é que, ao ler de uma lista ? super T, o compilador sabe apenas que os elementos são algum supertipo desconhecido de T.
O único tipo seguro para leituras é 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);
}
}Por que a leitura é limitada
Uma List<? super Integer> pode, na realidade, ser uma List<Object> contendo textos.
Assim, uma leitura poderia retornar qualquer objeto. O compilador não pode garantir um valor inteiro; por isso, as leituras fornecem apenas 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());
}
}Caso de uso de consumidor
Use ? super T quando um método apenas consome valores, ou seja, quando apenas escreve neles.
Um método que preenche uma coleção de destino é o caso clássico.
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);
}
}A adição de subtipos também funciona
Com ? super Number, você pode adicionar qualquer valor numérico ou seus subtipos, como tipos inteiros, de precisão dupla e longos.
O limite inferior garante que a lista aceite pelo menos valores numéricos, portanto todos os subtipos são aceitos.
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);
}
}Estilo de Collections.addAll
O JDK usa limites inferiores para destinos. Por exemplo, um método genérico que insere elementos em um destino.
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);
}
}Comparador com supertipo
Um uso prático: Comparator<? super T> permite que uma ordenação aceite um comparador escrito para um supertipo.
Um comparador que compara qualquer objeto usando toString pode ordenar uma lista de textos.
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);
}
}Os curingas de supertipo e subtipo são imagens espelhadas
Os dois curingas são opostos:
? extends T: lê T, não pode escrever. É um produtor.? super T: escreve T, lê apenas Object. É um consumidor.
Essa simetria é o coração da regra PECS, que você aprenderá a seguir.
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);
}
}Copiando entre limites
Um método copy mostra os dois curingas ao mesmo tempo: lê de ? extends T e escreve em ? 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);
}
}Quando não usar um curinga
Se um método lê e escreve T, não use um curinga. Use um tipo exato ou um parâmetro de tipo nomeado.
Os curingas existem precisamente para os casos somente de leitura ou somente de escrita.
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);
}
}Verificação rápida
Teste sua compreensão dos limites inferiores.
Recapitulação
Você aprendeu sobre curingas com limite inferior:
? super Tsignifica um supertipo desconhecido de T.- Você pode escrever T e seus subtipos (um consumidor).
- As leituras retornam apenas Objeto.
- Ele é exatamente o espelho de
? extends T.
A seguir, a regra que conecta os dois: 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);
}
}Perguntas Frequentes
A aula “Curingas com limite inferior” é grátis?
Sim — o texto completo de “Curingas com limite inferior” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Curingas com limite inferior”?
? super T para consumidores. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Curingas com limite inferior”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Curingas com limite superior
- Curingas com limite inferior
- O princípio PECS
- Curingas em APIs