Pequena dúvida em genéricos

2 respostas
T
import java.util.*;

public class GenericoString
{
	public void takeList(List<? extends String> list){
		list.add("teste");
	}

	public static void main(String... args){
		GenericoString gs = new GenericoString();

		gs.takeList( new LinkedList<String>() );
	}
}

Por que não se pode fazer list.add("teste"); ?? Quando vc usa vc não está dizendo que qualquer subclasse de String (incluindo a própria classe String) poderá ser usada?

Outra coisa, neste caso, o único tipo permitido ali é a própria String não? Uma vez que a classe String é final...

Obrigado!

2 Respostas

tnaires

Como você bem observou, a classe String é final. Por isso nem vale a pena escrever List<? extends String>, é melhor trabalhar diretamente com List<String>.

De qualquer forma, nunca é seguro adcionar elementos a uma collection que usa wildcards. Veja este link:
http://java.sun.com/docs/books/tutorial/extra/generics/wildcards.html

victorwss

Primeiramente, como o tnaires disse aí em cima, <? extends String> não faz sentido, pois String é final. No entanto, a linguagem permite isso e o javac não chia, empora o compilador do eclipse vá te dar uma warning (e com razão).

No entanto, sabemos que isso pode aparecer na prova para cobrar o seu conhecimento, mesmo que não tenha sentido. Então, vamos supor que faça sentido e vamos supor que exista uma subclasse de String chamada String2, assim List<? extends String> poderia ser List<String> ou List<String2>. Quando você dá um list.add("teste"); está adicionando um objeto da classe String em uma lista que pode ter um tipo mais restrito, pode ser uma List<String2>.

Esse é o tipo de coisa bem confusa e non-sense que aparece na prova. Para ficar mais fácil de entender, vamos usar Animal em lugar de String, aonde você tem uma classe Animal e tem subclasses Gato, Cachorro, Cavalo, etc. Se você tem uma List<? extends Animal>, isto pode ser List<Cachorro>, List<Gato>, List<Cavalo>, ou simplesmente List<Animal>.

Se você tiver isso:
public class Foo {
    private Animal teste;

    public void bar(List&lt;? extends Animal&gt; lista) {
        lista.add(teste);
    }
}
Você vai ter esse mesmo erro que você teve com String, com a mesma causa. No entanto aqui, as coisas ficam bem mais óbvias. Você tem um Animal teste, que você não sabe qual animal é. Vamos supor que seja um cavalo, mas o compilador não vai saber disso. List<? extends Animal> pode ser um List<Gato> ou um List<Cachorro>, e você não pode adicionar um animal qualquer neles, porque vai que esse animal é um cavalo? O compilador percebe que o elemento que está sendo inserido PODE NÃO SER específico o suficiente para que a adição seja válida, logo você tem um erro de compilação.
Criado 23 de janeiro de 2010
Ultima resposta 24 de jan. de 2010
Respostas 2
Participantes 3