dúvida sobre Generics. Utilização do 'extends' e o 'super'

Olá !!!

Alguém poderia me ajudar ?

Por que quando utilizo ‘List<? super Pai>’ eu consigo adicionar ‘Filho’ e ‘Filha’ ao conjunto ?

import java.util.List;
import java.util.LinkedList;

class Pai{}
class Filho extends Pai{}
class Filha extends Pai{}

public class Main{                             
     public static void main(String agss[]){          
              
              List<? extends Pai> p1 = new LinkedList<Pai>();      //linha1
              p1.add(new Filho());
              p1.add(new Filha());
              
              List<? super Pai> p2 = new LinkedList<Pai>();            //linha2
                                        
              p2.add(new Filho());
              p2.add(new Filha());          
       } 
}

Qual é a diferença entre a linha1 e a linha2 ???

Primeiro, este código não compila, pois você não pode adicionar nada na lista quando usa o extends.

public void teste(List<? extends Pai>){}// Este método so recebe listas que foram "tipadas" com a classe Pai ou subclasses da mesma 
public void teste(List<? super Pai>){}// Este método so recebe listas que foram "tipadas" com a classe Pai ou superclasses da mesma  

Espero que ajude,
Flw

Olá eusoufeioedai,
o método add é perigoso, pois ele pode adicionar algum tipo impróprio na coleção.
Quando você usa o coringa <?>, você está dizendo ao compilador que você vai usar qualquer tipo genérico do tipo do argumento declaro, e vai invocar apenas métodos para lerem dados, e não para [b]escreverem/b dados.
É por isso que o seu código não compila, experimente usar outra função que não modifique o conjunto. Por exemplo: [code]import java.util.List;
import java.util.LinkedList;

class Pai{}
class Filho extends Pai{}
class Filha extends Pai{}

public class Main{
public static void main(String agss[]){

          List<? extends Pai> p1 = new LinkedList<Pai>();      //linha1

// p1.add(new Filho());
// p1.add(new Filha());
p1.size();
List<? super Pai> p2 = new LinkedList(); //linha2

// p2.add(new Filho());
// p2.add(new Filha());
p2.size();
}
}[/code]
Para add um objeto na coleção de uma forma segura, use a palavra super:[code]import java.util.List;
import java.util.LinkedList;

class Pai{}
class Filho extends Pai{}
class Filha extends Pai{}

public class Main{
public static void main(String agss[]){

          List<? extends Pai> p1 = new LinkedList<Pai>();      //linha1

// p1.add(new Filho());
// p1.add(new Filha());
p1.size();
List<? super Filho> p2 = new LinkedList(); //linha2

            p2.add(new Filho());

// p2.add(new Filha());
p2.size();
}
}[/code]

<? super Filho>… você estará pedindo ao compilador que aceite um tipo genérico que seja um Filho ou um supertipo de Filho.

<? extends Pai>… você estará pedindo ao compilador que aceite o tipo Pai e qualquer subtipo de Pai, apenas para leitura.

Qualquer dúvida, poste ae!

Abraço!

acho que entendi

No livro da certificação, a autora explica isso. Você pode adicionar qualquer elemento abaixo na arvore de herança, o seu objeto é do tipo Pai, já o List recebe qualquer lista que for pai ou superclasse da mesma. Tenta faze isso:

List<? super Pai> p2 = new LinkedList<Filho>();

E veja o que acontece.
Flw

deixa eu ver se entendi:

List<? extends Pai> —>Toda declaração que for "? extends" roda sem problema, mas não pode adicionar itens ao conjunto, é isso né ?


De acordo com o código abaixo

class Avo{}

class Pai extends Avo{}

class Filho extends Pai{}
 

As declarações possíveis são:

       ---------------
          List&lt;? super Avo&gt; p2 = new LinkedList&lt;Avo&gt;();                                                   
          p2.add(new Avo());                                 
          p2.add(new Pai());                                 
          p2.add(new Filho());                      
       
        ------------- 
          List&lt;? super Pai&gt; p2 = new LinkedList&lt;Avo&gt;();                                                   
       //   p2.add(new Avo());    &lt;--------------Gera erro                             
          p2.add(new Pai());                                 
          p2.add(new Filho());

        ------------- 
          List&lt;? super Filho&gt; p2 = new LinkedList&lt;Avo&gt;();                                                   
       //   p2.add(new Avo());    &lt;--------------Gera erro                             
       //   p2.add(new Pai());     &lt;--------------Gera erro                                                            
          p2.add(new Filho());                                 



é mais ou menos isso ???

É isso mesmo.
:grin: