Dicas sobre genéricos

30 respostas
anderson.bonavides

Galera alguêm pode me dar uma dicas sobre os genéricos e também sobre sua declaração?

30 Respostas

T

“Generics” - é melhor ler um livro (como o da Kathy), porque eles são complicados demais para explicar apenas com “dicas”.

O “FAQ” oficial tem mais de 200 páginas (http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.pdf), e o “tutorial” do Gilad Bracha (http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf) também é imenso.

Por isso, é melhor ler o livro da Kathy.

anderson.bonavides

Ok thingol, mas caso eu fosse fazer a prova hoje que conselho vc me daria?

T

Eu demorei um bocadinho até pegar o “jeitão” do “generics”; por isso é que digo que você precisa ler o livro com atenção e praticar um bocado com o javac, até pegar o jeito.

anderson.bonavides

:frowning:

Ok, mas de qualquer forma deixo o tópico aberto a dicas.
Obrigado!

anderson.bonavides

Vou mandar esta aqui para vocês. É uma dúvida também minha.

import java.util.List;
public class AddString {
	public void addStrings(List list){
		list.add("foo");
		list.add("bar");
	}
	
}

What must you change in this method to compjile without warnings?
A. add this code after line 11:
list = (List ) list;

B. change lines 12 and 13 to:
list.add("foo");
list.add("bar");

C. change the mothod signature on line 11 to:
public void addStrings(List list){

D. change the method signature on line 11 to:
public void addStrings(List list){

E. No changes are necessary. This method compiles without warnings.

O Killer diz que a resposta correta é a letra D. Mas pelo que compilei aqui todos geraram saida com mensagens de advertência.

J

Realmente a D é a correta. Mas como vc disse que compilou com avisos, para que não restassem dúvidas eu compilei o código aqui e não apareceram avisos.
[Adicionado] Ou melhor ainda, se o código que vc postou é exatamente esse a resposta seria a letra E, pq a D é redundante, pq o código já está como a opção sugere.

anderson.bonavides

É javadev realmente tem um erro no parametro do método. Vou corrigir.

anderson.bonavides

Corrigido… Realmente o erro foi meu. Verifiquei aqui que não gera mensagens de erro.
Muito obrigado javadev, mas vc pode me explicar pq as outras opções não rolam?

Agradeço. :slight_smile:

F

Ai anderson.bonavides seu codigo esta assim com a corecao para letra D??

public class Try {
    
    public static void addStrings(List<? super String> list){   
        list.add("foo");   
        list.add("bar");   
 }
    public static void main(String...a) throws Throwable{
              
              List l=new ArrayList();
              addStrings(l);
             }
    
}

pq a menos que nao se altere o “tipo” da variavel local List TAMBEM para String ,aqui tambem gera compilacao com erros ,entao a opcao D a meu parer estaria errada

anderson.bonavides

fabio depois da correção funfou blz!

:wink:

F

anderson.bonavides:
fabio depois da correção funfou blz!

:wink:


Que loucura aqui ainda assim manda avisos!!! :frowning:

J

A. add this code after line 11:
list = (List ) list;
Compila com aviso pq vc pode passar um conjunto de qq coisa e pode ter problemas.

B. change lines 12 and 13 to:

list.add(foo);

list.add(bar);

Não compila não existe isso list.add(foo) .

C. change the mothod signature on line 11 to:
public void addStrings(List <? extends String> list){
Não compila, vc não pode adicionar quando utiliza ? extends String, se fosse ? super String OK compilaria sem avisos.

D. change the method signature on line 11 to:
public void addStrings(List<? super String> list){
Compila sem avisos com ? super String vc pode adicionar.

E. No changes are necessary. This method compiles without warnings.
Modificações são necessárias no caso a sugerida na opção D.

anderson.bonavides

Já tentou dar um clean no teu projeto?
rsrs

F

aqui so da certo assim

public static void addStrings(List<? super String> list){   
        list.add("foo");   
        list.add("bar");   
    }  
   
   

          public static void main(String...a) throws Throwable{
              
           List<String> l=new ArrayList<String>();//acrescentando o tipo!!
              addStrings(l);
anderson.bonavides

A. add this code after line 11:
list = (List ) list;
Compila com aviso pq vc pode passar um conjunto de qq coisa e pode ter problemas.

Sobre a letra A. Para compilar com avisos não seria nescessário modificar o parametro para deixar sem tipo nenhum?

F

ei cara, manda ai o codigo fonte com a mudanca para nao dar erro :wink:
so para verificar como vc declaraou embaixo a variavel local

anderson.bonavides
fabioEM:
ei cara, manda ai o codigo fonte com a mudanca para nao dar erro :wink: so para verificar como vc declaraou embaixo a variavel local
Segue:
import java.util.*;

public class AddString {
	public void addStrings(List list){
		list.add("foo");
		list.add("bar");
	}
	public static void main(String[] args) {
		ArrayList e = new ArrayList();
//		e.add("and");
		AddString  a = new AddString();
		a.addStrings(e);
	}
}

Teu código também ta compilando sem avisos aqui. To pensando que tu não colocou o import corretamente. =/

F
anderson.bonavides:
fabioEM:
ei cara, manda ai o codigo fonte com a mudanca para nao dar erro :wink: so para verificar como vc declaraou embaixo a variavel local
Segue:
import java.util.*;

public class AddString {
	public void addStrings(List list){
		list.add("foo");
		list.add("bar");
	}
	public static void main(String[] args) {
		ArrayList e = new ArrayList();
//		e.add("and");
		AddString  a = new AddString();
		a.addStrings(e);
	}
}

To pensando que tu não colocou o import corretamente. =/

nao o import esta certo, mas do jeito que ta compila com avisos ne?

J

Sobre a letra A. Para compilar com avisos não seria nescessário modificar o parametro para deixar sem tipo nenhum?


Pelo que entendi essa modificação seria no corpo do método e não na sua assinatura.

F

Pois é se fosse assim ai aqui no meu compilador daria certo javadev

class T{
   public static void addStrings(List y){  
        List<? super String>  list=null;
        list.add("foo");
        list.add("foo");   
        list.add("bar");   
    }  
   
   

          public static void main(String...a) {
              
          ArrayList l=new ArrayList();
           addStrings(l);

  }
}

mas a resposta é
D. change the method signature on line 11 to:
public void addStrings(List<? super String> list) ou seja mudanca explicita no metodo!!! :frowning:

anderson.bonavides
fabioEM:
anderson.bonavides:
fabioEM:
ei cara, manda ai o codigo fonte com a mudanca para nao dar erro :wink: so para verificar como vc declaraou embaixo a variavel local
Segue:
import java.util.*;

public class AddString {
	public void addStrings(List list){
		list.add("foo");
		list.add("bar");
	}
	public static void main(String[] args) {
		ArrayList e = new ArrayList();
//		e.add("and");
		AddString  a = new AddString();
		a.addStrings(e);
	}
}

To pensando que tu não colocou o import corretamente. =/

nao o import esta certo, mas do jeito que ta compila com avisos ne?

É esqueci de modificar o parametro do método.
Segue corrigido:

import java.util.*;

public class AddString {
	public void addStrings(List<? super String> list){
		list.add("foo");
		list.add("bar");
	}
	public static void main(String[] args) {
		ArrayList e = new ArrayList();
//		e.add("and");
		AddString  a = new AddString();
		a.addStrings(e);
	}
}
F

E ta doido mesmo meu compilador
agora ta funcionando nossa que mico!! :oops:

anderson.bonavides

javadev

Sim vc ta certo. Mas para mim esses avisos só seriam gerados por linha de comando. Como fica a regra no caso de argumentos?

F

anderson.bonavides:
javadev

Sim vc ta certo. Mas para mim esses avisos só seriam gerados por linha de comando. Como fica a regra no caso de argumentos?

Cara agora deu um nó no meu cerebro :frowning:

anderson.bonavides

kkkk
Desulpa mas corrigindo. Não por linha de comando mas por declaração. Como por exemplo: http://www.guj.com.br/posts/list/80968.java

A opção 1.

F
Resumindo não sei se pode te ajudar mas eu tinha feito um resuminho que é o seguinte:
class Animal {
    
}
class Canine extends Animal{
    
}
class Dog extends Canine{
    
}

   static void x(List<? extends Animal> lista){1)
      
    }
  static<T extends Animal> void x(List...lista){2)
        
    }
Quando se trata de argumentos só vale [? extends super] para o caso 2 metodo genéricos [ elemento extends Tipo] elemento=T Essa peguei do livro java use a cabeça. No exemplo acima vc usa um tipo genérico para não ter que todas vezes manualmente para cada parametro especificar os limites,então é uma otima sacada!! Para criação de variáveis, não tem sentido o T como elemento mas ou serve so para referenciar subtipos exemplo:
ArrayList<? extends Animal> animal=new ArrayList<Animal>();
       ArrayList<Dog> dog=new ArrayList<Dog>();
       animal=dog;
animal pode referenciar seus subtipos e se tu fizer:
ArrayList<? super Dog> dog=new ArrayList<Dog>();
       ArrayList<Animal> animal=new ArrayList<Animal>();
       dog=animal;
aqui vc tem um dog que referencia um tipo que esta acima na arvore!!! :lol:

E por fim para classes nao vale o ? o resto vale!!
Se alguem tiver mais resumos ai seria uma boa!!

anderson.bonavides
fabioEM:
Resumindo não sei se pode te ajudar mas eu tinha feito um resuminho que é o seguinte:
class Animal {
    
}
class Canine extends Animal{
    
}
class Dog extends Canine{
    
}

   static void x(List<? extends Animal> lista){1)
      
    }
  static<T extends Animal> void x(List...lista){2)
        
    }
Quando se trata de argumentos só vale [? extends super] para o caso 2 metodo genéricos [ elemento extends Tipo] elemento=T Essa peguei do livro java use a cabeça. No exemplo acima vc usa um tipo genérico para não ter que todas vezes manualmente para cada parametro especificar os limites,então é uma otima sacada!! Para criação de variáveis, não tem sentido o T como elemento mas ou serve so para referenciar subtipos exemplo:
ArrayList<? extends Animal> animal=new ArrayList<Animal>();
       ArrayList<Dog> dog=new ArrayList<Dog>();
       animal=dog;
animal pode referenciar seus subtipos e se tu fizer:
ArrayList<? super Dog> dog=new ArrayList<Dog>();
       ArrayList<Animal> animal=new ArrayList<Animal>();
       dog=animal;
aqui vc tem um dog que referencia um tipo que esta acima na arvore!!! :lol:

E por fim para classes nao vale o ? o resto vale!!
Se alguem tiver mais resumos ai seria uma boa!!

Se tratando de resumos eu tenho axo que 2 ou 3. Vou postar para vocês aqui.

F

boa anderson.bonavides se preparando tambem para prova ne?? :smiley:

J

anderson.bonavides:
kkkk
Desulpa mas corrigindo. Não por linha de comando mas por declaração. Como por exemplo: http://www.guj.com.br/posts/list/80968.java

A opção 1.


Nesse caso o que está acontecendo é a mistura de código antigo (sem utilização dos genéricos) com código mais novo (utilizando genéricos).
Vc está passando um TreeSet sem especificar tipo, para um método que seu parâmetro é um Set de tipo Dog2.

anderson.bonavides

Segue 3 resumos legais:

1º) Navegação de arquivos e ES.
2º) Generics
3º) Exceptions

Tudo bem básico mas ta bem legal. Principalmente o ultimo.

Criado 10 de fevereiro de 2008
Ultima resposta 10 de fev. de 2008
Respostas 30
Participantes 4