Duvida Sobre Metodos Genericos

Pessoal alguem poderia me explicar a assinatura desse metodo generico…

O que eu gostaria de saber é como eu faça para usar esse metodo tipo o que eu posso passar para ele e o motivo.!!!

Você só pode passar objetos do tipo de uma classe que implementa List (ArrayList, Vector, LinkedList, etc) e o tipo genérico deve ser algo que herda de Number (Integer, Long, Float, Double, etc.), já que o tipo do parâmetro é List e antes do tipo de retorno do método você declarou que o tipo E herda de Number ().

Já o retorno só pode ser atribuido a algo que List passa no teste É-UM (List, Collection, Object, etc) e que não tem tipo genérico.

Essa parte relacionada ao tipo genérico só percebi testando. Não consegui uma explicação, pois achei que o retorno poderia ser atribuído a por exemplo um tipo cujo genérico é Number, já que o tipo genérico do retorno é <? super E> e E herda de Number, mas não pode… mesmo se o genérico for Object tb não pode. Fica aí uma pergunta pra alguém que saiba responder.

Exemplos de uso validos:

process(new ArrayList<Double>()); //sem atribuir o retorno a nada
process(new Vector<Integer>()); //sem atribuir o retorno a nada
process(new LinkedList<Float>()); //sem atribuir o retorno a nada
List l1 = process(new ArrayList<Double>()); //atribuindo a algo do tipo List, sem informar o tipo genérico, o que compila com warning
Collection l2 = process(new Vector<Integer>()); //atribuindo a algo do tipo Collection, sem informar o tipo genérico, o que compila com warning
Object l3 = process(new LinkedList<Float>()); //atribuindo a algo do tipo Object, sem informar o tipo genérico, o que compila com warning

Exemplos de uso invalidos:

List<Number> l4 = process(new ArrayList<Double>()); //erro por causa do tipo genérico do retorno.
Collection<Double> l5 = process(new Vector<Double>()); //erro por causa do tipo genérico do retorno.

RafaelVs a unica coisa que eu não entendi é o seguinte cara… qual o tipo de retorno que um tipo List pode aceitar ???Pelo que eu sei cara não seria tudo que estaria acima de da arvore de herança de E ???

tipo

List<Double> esse = process(new ArrayList<Double>());

Cara eu não to conseguindo entender o que esse metodo ai pode retornar na verdade eu to muito confuso sobre isso se alguem puder exclarecer eu agradeceria !!!

Outra coisa tbm não consigo inserir nada no List array dentro de metodo sem fazer um cast de E por que isso pessoal ???

Raff, eu não sei a explicação do ponto de vista da especificação (não fui atrás do javadoc pesquisar).

Mas a explicação que eu vejo (e acho que deve ser aceitável) é que o compilador não permite você atribuir nenhuma variável de um tipo que use coringa (a interrogacao), já que não tem como o compilador saber o tipo exato.

Por exemplo, você não pode atribuir o parâmetro do seu método a nenhuma variável que use generics porque no seu caso E é do tipo , então veja o problema se isso fosse permitido:

List<? extends Number> l1 = new ArrayList<Double>(); //perfeitamente válido
List<Integer> l2 = l1; //tudo bem que Integer extends Number, mas o tipo <? extends Number> não necessariamente vai ser um Integer, como vimos na atribuição de l1 e, por isso, dá erro de compilação.

No retorno é parecido, mas o problema é um pouco diferente. O problema está relacionado aos usos posteriores da variável que recebe o retorno do método.

Exemplo:

List<Number> l3 = process(new ArrayList<Integer>()); //vamos imaginar que foi retornado um ArrayList<Integer>;
l3.add(2.5); //Note o erro... o objeto é do tipo ArrayList<Integer>, mas como a variável é do tipo List<Double> eu posso inserir um Double a uma lista de Integer.

Acho que é por isso que não podemos atribuir nem objetos do tipo <? extends XXX> nem <? super XXX> a tipos genéricos (note que, como falei antes, vc pode atribui-los a tipos não genericos, como List, Collection ou Object.

[]'s

public static :Vc atribui qualquer classe que extends a Number{Integer,Double,Long…}

List<? super E> :sendo ‘E’ um tipo generico,ele pode receber qualquer objeto…se por exemplo o objeto recebido for um ‘Integer’ …vc pode atribuir um Interger e qualquer classe acima dele…tal como O ‘Number’ e ‘Object’

process(List nums){} :aqui vc escolhe o tipo de lista que deseja…se for um tipo String…o generico ‘E’ que significa Elemento …vai se transformar em String…ficando Listnums