Duvida usando generics - Coringa

8 respostas
B

Boa tarde!

Tenho uma duvida na utilização do coringa! Minha duvida e a seguinte:

Quando faço o comando a baixo dá erro:

Integer[] arraySuper = new Integer[]{1,2,3,5,8,13};

List<? super Integer> listaCuringaSuper = new ArrayList<Integer>();

listaCuringaSuper.addAll(Arrays.asList(arraySuper));
listaCuringaSuper.add(21);
listaCuringaSuper.add(34);
		
Number number = (Number) listaCuringaSuper.get(5); // retorna 8
		
listaCuringaSuper.add(number); // Erro de compilação

Segundo a teoria de generics, quando uso o <? super T> significa que a própria classe ou uma super classe de T são aceitas. Me corrigam se estiver errado. So que o problema é que Integer estende Number! E porque dá erro de compilação?

Agora se eu fizer o codigo a baixo:

List<Number> number = new ArrayList<Number>();
number.add(5);
number.add(6);
number.add(7);
		
List<? super Integer> listaCuringaSuper = number;

Por que ele não da erro de compilação???

Se alguem puder me ajudar nessa duvida… agradeço
Abraços,

8 Respostas

M
<? super T> não é "a própria classe ou uma super classe de T", é "uma classe, cuja superclasse seja T, ou ela mesma (T)" ou seja, no teu caso, listaCuringaSuper só vai aceitar Integer ou outra classe que extenda Integer, mas como Integer é final e não pode ter classes filhas, listaCuringaSuper só vai aceitar Integer mesmo.
O

maschiojv:
<? super T> não é “a própria classe ou uma super classe de T”, é “uma classe, cuja superclasse seja T, ou ela mesma (T)”

ou seja, no teu caso, listaCuringaSuper só vai aceitar Integer ou outra classe que extenda Integer, mas como Integer é final e não pode ter classes filhas, listaCuringaSuper só vai aceitar Integer mesmo.

acho que a quetão é… pq o listaCuringaSuper aceitou number, sendo que number é do tipo List… acho que é que a linha

List<? super Integer> listaCuringaSuper = number; seja possivel por uma propriedade de herança, já que Number é a classe pai de Integer, entao todo objeto Integer é também um objeto Number e a linha listaCuringaSuper.add(number); // Erro de compilação ocorre um erro pq a adicão de um novo elemento a lista deve ser do tipo Integer, respeitando o generics

M

… apaguei pq tinha falado besteira :slight_smile:

B

Deixa ve entendi:

Quando tenho <? super Integer> ele so aceitam a propria classe ou as classe que sejam filhos de Integer ?

Se foi isso então qual e a diferença entre <? extends Integer> e <? super Integer>?

Eu conhecia a seguinte definição:

<? extends Integer> --> "A propria classe ou uma subclasse de" <? super Integer> --> "A própria classe ou uma superClasse de" To mais confuso que antes! huahhhua
O
<? super Integer>: classe Integer ou qualquer superclasse de Integer, como Number e Object. <? extends Integer>: classe Integer ou qualquer classe que extenda Integer (subclasses).
B

Pessoal melhor! Criei 4 classes:

ClasseA:

public class ClasseA {

}

ClasseB:

public class ClasseB extends ClasseA {

}

ClasseC:

public class ClasseC extends ClasseB {

}

ClasseD:

public class ClasseD extends ClasseC{

}

Ai criei o seguinte teste:

public void testeHierarquia(){
		
		ClasseA a = new ClasseA();		
		ClasseB b = new ClasseB();
		ClasseC c = new ClasseC();
		ClasseD d = new ClasseD();
		
		
		List<? super ClasseB> list1 = new ArrayList<ClasseB>();
		
		list1.add(a); // Erro
               list1.add(b);
		list1.add(c); 		
		list1.add(d);
		
		
		List<? extends ClasseB> list2 = new ArrayList<ClasseB>();
		
		list2.add(a); //Erro
		list2.add(b); //Erro
		list2.add(c); // Erro
		list2.add(d); // Erro		
		
	}

Bom na list1 entendo que ele so aceita o B ,C e o D, pois, <? super ClasseB> aceita a propria classe B e as classes que estendam B.

Agora a duvida:

Por que na list2 todos dão erro???

Gera o seginte erro no eclipse:

The method add(capture#11-of ? extends ClasseB) in the type List<capture#11-of ? extends ClasseB> is not applicable for the arguments (ClasseA)
B

Então… alguma opnião? alguem? Obrigado

E

Tambem estava com dúvidas quanto aos coringas.
A fim de ajudar quem possa passar por estas dúvidas, segue classe que implementei e que responde os questionamentos do tópico.

import java.util.ArrayList;
import java.util.List;

public class CoringasEmListas {

	static class A{
		private String nome;
		public A(String nome){ this.nome = nome; };
		public String toString() { return nome; }
	}
	static class B extends A{
		public B(String nome) { super(nome); }
	}
	static class C extends B{
		public C(String nome) { super(nome); }
	}
	static class D extends C{
		public D(String nome) { super(nome); }		
	}
	
	public static void main(String[] args) {
		A a = new A("A");
		B b = new B("B");
		C c = new C("C");
		D d = new D("D");
		
		//Listas com ? extends, podem ser criadas para as classes cujo objeto instanciado passe no teste É-UM da classe informada
		//List<? extends B> listaExtends0 = new ArrayList<A>(); //Um objeto de A não passa no teste É-UM de B
		List<? extends B> listaExtends1 = new ArrayList<B>();
		List<? extends B> listaExtends2 = new ArrayList<C>();
		List<? extends B> listaExtends3 = new ArrayList<D>();
		
		//listas com ? extends são somente leitura para inserção de objetos
		//listaExtends1.add(a);//inválido
		//listaExtends1.add(b);//inválido
		//listaExtends1.add(c);//inválido
		//listaExtends1.add(d);//inválido
		
		//Listas com ? super, podem receber qualquer objeto com hierarquia igual ou superior à classe informada
		List<? super B> listaSuper0 = new ArrayList<A>();//A é super classe de B, ok !
		List<? super B> listaSuper1 = new ArrayList<B>();//B é a própria classe, ok !
		//List<? super B> listaSuper2 = new ArrayList<C>();//C extends B, por isto não pode ser usada
		//List<? super B> listaSuper3 = new ArrayList<D>();//D extends C e B, por isto não pode ser usada

		//listas com ? super, podem ter objetos inseridos, desde que este objeto passe no teste É-UM da classe informada 
		//listaSuper0.add(a);//a não passa não É-UM B
		listaSuper0.add(b);
		listaSuper0.add(c);
		listaSuper0.add(d);
		
		
	}
	
}
Criado 25 de maio de 2009
Ultima resposta 24 de ago. de 2009
Respostas 8
Participantes 4