Galera, minha dúvida é bem direta: qual a real utilidade de usar <? extends [CLASS]>??
::: onde [CLASS] é o nome de uma classe ou interface
Entendo que: usando uma declaração genérica, ao ser instanciada, uma classe passa a ter um tipo fixo para seus parâmetros (no caso das coleções).
Quando eu instancio uma nova coleção, eu defino através do < type > qual o tipo de dados que será armazenado na coleção. Digamos que eu instancie uma List com List list = new List< Collection >()
Nela estamos definindo que poderemos inserir QUALQUER objeto que seja uma Collection. Isso permite, é claro, que qualquer classe que implemente direta ou indiretamente a interface Collection poderá ser adicionada à "list".
Isso pq, uma vez que uma classe própria do usuário estenda Collection, ela passa a ter um relacionamento "é um" com esta.
Agora vejamos na prática:
- classe genérica Journal (a usarei para meus exemplos) -
public class Journal< T >
{
private T core;
public Journal< T >(T obj)
{ set(obj); }
public void set(T obj)
{ this.core = obj; }
}
Agora uma classe que estenderá Journal
public class JournalModel
{
private String core;
public JournalModel(String core)
{ this.core = core; }
}
E a classe que será um JournalModel:
public class MeuJournal extends JournalModel
{
public MeuJournal(String txt)
{ super(txt); }
}
Agora uma classe que usa a classe Journal:
public class JournalTest
{
public static void main(String[] args)
{
JournalModel jm = new JournalModel("teste journalmodel");
Journal< JournalModel > j = new Journal< JournalModel >(jm);
MeuJournal mj = new MeuJournal("teste meujournal");
j.set(mj);
}
}
Notemos que: MeuJournal "é um" JournalModel.
Percebamos que no código: primeiro instancio um JournalModel.
Depois eu instancio um Journal declarando como seu tipo (já que é uma classe genérica) como JournalModel, e passo como argumento ao construtor o meu objeto JournalModel instanciado anteriormente.
Ou seja, se o tipo da minha variável Journal é JournalModel, então um objeto JournalModel tem de ser adicionado sem problemas!
Em seguida instanciei um objeto MeuJournal. Lembre-se que ele estende JournalModel e, portanto, "é um" JournalModel. Então eu o passo para o objeto Journal, pq MeuJournal "é um " JournalModel, correto?
Então agora me diz, por que eu usaria < ? extends JournalModel >, se, bastando minha classe estender JournalModel, ela já "é um" JournalModel?
Qual a diferença entre eu declarar assim:
j = new Journal< JournalModel >();
e
j = new Journal< ? extends JournalModel >();
???
Aproveitando o gancho, qual a utilidade de se usar: < ? super JournalModel > ???
Alguém poderia dar um exemplo de "quando" isso seria útil?
Desde já agradecido pelos potenciais esclarecimentos.