Dúvida genérics

Galera li no livro da Keity que quando um método possui um parâmetro
genérico, esse só recebe como argumento o tipo específicado no parâmetro genérico.

Por exemplo:

	public static void m (List<String> list) {
		System.out.println("List");
	}

O método m pelo que eu li, só poderia receber uma List, e o polimorfismo
só se aplica ao tipo base. Pois bem, fazendo simulados aqui, descobri que posso passar
para esse parâmetro um List sem tipo parametrizado.

Por exemplo:

	public static void main(String[] args) {
		List<String> least = new ArrayList<String>();
		List list = new ArrayList();
		meth(list); // tipo não parametrizado... [b]PORQUE ISSO FUNCIONA ????[/b]
		meth(least); // tipo parametrizado, ok.
	}

	public static void meth(List<String> list) {
		System.out.println("List");
	}

Se os genéricos são uma proteção estritamente de tempo de compilação, o compilador
não deveria resolver isso ?

Grato

Funcionar funciona, mas provavelmente vai te gerar um “Warning”, to sem compilador aqui, mas 99,9% de certeza que isso te gera um warning.

Ou seja vc tem um List list , que espera um objeto do tipo List, quando vc passa pra ele um objeto do tipo sem o uso de Generics funciona, porque vc entraria nesse caso:

E isso é valido :smiley:

Bom, não sabia que dava pra fazer nenhum dos dois…
Quando eu faço isso:

		List<String> lista = new ArrayList();

Isso implica em que Evertom ?

Já que estou no embalo - isso também funfa:

	List lista2 = new ArrayList<String>();

Existem implicações em algum dos casos ?
E porque uma variável declarada para receber um tipo específico de list
pode receber um que " add tudo " ???

Brigadão mais uma vez !

Isso funciona…
pois o tipo com parametro previne em tempo de compilação que seja passada uma List com parametro diferente!

Ex:

public void test(List<String> list) {}

esse método previne em tempo de compilação que você passe um List<“Qualquer coisa que nao seja uma String”>

List<Integer> l = new ArrayList<Integer>(); test(l) // Erro de compilação pois o método aceita somente List<String>

List l = new ArrayList(); test(l) // Compila com Warning.

No livro SCJP explica isso direitnho… a principal razão para isso não causar erros de compilação é pelo fato de existi muitos codigos antigos que não trabalhem com Generics, logo quando voce trabalha com Collections sem Generic quase tudo compila mas lhe lança warnings…

Então Gustavo, quando agente faz:

Esse codigo acima em tempo de compilação vc vai enchergar todos os métodos da interface List devido ao casting que ocorre implicitamente mas que eu coloquei ali so pra vc ver, como vc defeniu o generics , o método add por exemplo ficará add(String e), em tempo de execução que vc vai utilizar o uso do polimorfismo se houver algum método sobreescrito na classe ArrayList.

agora se agente faz:

Em tempo de compilação novamente veremos todos os métodos de List devido ao casting, como List agora nao foi parametrizado com Generics o que vc verá no método add?

add(Object o), entao por isso se vc fizer do tipo acima vc vai adicionar, gato, cachorro, cavalo, anta, urubu, ornitorrinco e tudo mais que vc tem direito na sua lista.

Agora vejá so o problema que isso pode te causar, imagine que vc tenha um codigo extremamente grande cheio de Threads rsrs, e algo desse tipo no meio:

[code] public static void main (String… args){

      List list = new ArrayList();  
       list.add(1);
       meth(list); 	      
     	      
    }   
  
  

    public static void meth (List<String> list) {   
    	
    	list.add("2");

    	for(String a : list){
    		System.out.println(a);
    	}
    	
    }  [/code]

Ok… ClassCastExcepton ali quando tiver que fazer o for correto ?!

Aproposito, ótima explicação novamente…

[quote=Gustavo Santos]Ok… ClassCastExcepton ali quando tiver que fazer o for correto ?!

Aproposito, ótima explicação novamente…[/quote]

Isso mesmo ClassCastException, daí ficar fazendo instanceOf pra verificar se realmente o que vier for uma String não é nada agradável.