<? super T>

Pessoal,

Tenho essa declaração de método:

public static <T> List<T> backwards(List<? super T> input){ return null;}

Mas não entendi o ? super T. O que essa linha esta fazendo?

Qualquer classe que seja T ou ancestral de T.

esse :?: é um tipo curiga que vc está defindo.

? super T

esta dizendo que recebe como parametro qq coisa que esteja acima de sua sub-class na hierarquia de T.

se Cliente extends Pessoa…vc assumiria que T = Pessoa…

agora se fizer isso.

? extends T

esta dizendo que tudo que for subclasse de T.

num sei se ficou claro pra vc, qq coisa posta ai.

vlw!

uma coisa q não entendi tb…como ele coloca dois tipos de retorno???

public static List backwards(List<? super T> input){

só deixando claro que em
"? super T" o T também está incluído, ou seja aceita qualquer super classe de T e o próprio T

o mesmo é valido para “? extends T”, aceita qualquer sub-classe de T e o próprio T

o antes do List serve para declarar o tipo , já que T é um genérico.

Se não fosse assim, ele esperaria que T fosse uma interface/classe

[quote=mueller]o antes do List serve para declarar o tipo , já que T é um genérico.

Se não fosse assim, ele esperaria que T fosse uma interface/classe
[/quote]

HUmm…perai…xa eu ver se entendi…quando eu coloco assim List estou dizendo que retornara um objeto genérico T mas especializado para um List genérico?

Acho que assim fica mais fácil para explicar o porquê desse . Se você tiver um método assim

public List<String> getFoo(){...} Você sabe que vai retonar lista de string, não consegue usar esse método para retornar lista de inteiros.

Agora quando você constrói um método genérico

public List<T> getFoo(){...} (esse código não compila) a jvm não vai entender o que é esse <T> (exceto se você tiver uma interface/classe T), por isso você declara ele na assinatura do método, assim

isso não é mt usado no dia-a-dia neh? só em certificação pelo jeito

Não é só certificação, minha explicação não ficou boa, esse é fundamental para o uso de generics
Vamos lá denovo.

Imagine que você tem um método que recebe 2 objetos List, seu método precisa criar um Set e unir as 2 lists. O método também precisa ser genérico, deve trabalhar com listas de qualquer elemento.
Sem generics ficaria assim:

	public Set unir(List lista1, List lista2){
		Set s = new HashSet(lista1);
		s.addAll(lista2);
		return s;
	}

Sem utilizar o generic, você vai precisar fazer um cast quando chamar esse método, além de receber alguns warnings.
Agora para fazer esse método funcionar sem cast nem warnings, você reescreve assim

public <T> Set<T> unir(List<T> lista1, List<T> lista2){
		Set<T> s = new HashSet<T>(lista1);
		s.addAll(lista2);
		return s;
	}

Agora ele trabalha com listas de qualquer objeto, da mesma forma que o exemplo anterior só que sem a necessidade de cast e sem warnings.

Então você pode usar um

Set<String> setStrings = unir(umaListaStrings, outraListaStrings); Set<Integer> setInteger = unir(umaListaIntegers, outraListaIntegers);

O então que era a dúvida, é parte fundamental dos generics.

agora q eu entendi q é um simples cast…hehehe