Questão de Collections e Generics

Fala galera blz, estava fazendo um simulado da Caelum no site, e parei na seguinte questão:

 import java.util.ArrayList;
 import java.util.List;
 
 class Carro {}
 class Trabant extends Carro{}
 
 class Generics {
 
   public static void main(String[] args) {
     //aqui
     processaLista(carros);
   } 
   
   public static void processaLista(List<? extends Carro> lista) {
     //código complexo
   }
 } 

Quais das linhas abaixo (independentemente) deixa o código acima compila, substituindo o comentário “//aqui” (escolha tres opções)?

a) List carros = new ArrayList();
b) List carros = new ArrayList();
c) List carros = new ArrayList();
d) List<? extends Carro> carros = new ArrayList();
e) List carros = new ArrayList();
f) List<? extends Carro> carros = new ArrayList<? extends Carro>();
g) List carros = new ArrayList();

As respostas certas, são bcd

Agora alguém pode me explicar porque a letra A, e a letra F não está correta???

Valeu!!
Att

a) List carros = new ArrayList();
Quando você define um atributo com o tipo Generico, a criação do objeto deve possuir o mesmo tipo. Se isso fosse permitido você poderia inserir um carro qualquer no list de carros Trabant, e daria uma exception em tempo de execução.

f) List<? extends Carro> carros = [color=red]new ArrayList<? extends Carro>();[/color]
Não pode ser usado curinga no lado da criação do Objeto.

Eu acho que é isso!!!

Valeu

[quote=danielbussade]Fala galera blz, estava fazendo um simulado da Caelum no site, e parei na seguinte questão:

 import java.util.ArrayList;
 import java.util.List;
 
 class Carro {}
 class Trabant extends Carro{}
 
 class Generics {
 
   public static void main(String[] args) {
     //aqui
     processaLista(carros);
   } 
   
   public static void processaLista(List<? extends Carro> lista) {
     //código complexo
   }
 } 

Quais das linhas abaixo (independentemente) deixa o código acima compila, substituindo o comentário “//aqui” (escolha tres opções)?

a) List carros = new ArrayList();
b) List carros = new ArrayList();
c) List carros = new ArrayList();
d) List<? extends Carro> carros = new ArrayList();
e) List carros = new ArrayList();
f) List<? extends Carro> carros = new ArrayList<? extends Carro>();
g) List carros = new ArrayList();

As respostas certas, são bcd

Agora alguém pode me explicar porque a letra A, e a letra F não está correta???

Valeu!!
Att[/quote]

a) List carros = new ArrayList();
Não compila porque é diferente de . Os dois tipos genéricos tem que ser iguais.

f)f) List<? extends Carro> carros = new ArrayList<? extends Carro>();
Você não pode usar o <?> na criação do objeto. Só na DECLARAÇÃO.

[]s
Gunnar

Daniel é o seguinte o compilador para genericos ele vefirica os tipos em tempo de compilação e não em tempo de execução como é feito no caso de arrays Animal[] ani = new Dog[3]… Isso pode ser feito com arrays porque o compilador se preocupara com o tipo em tempo de execução…
agora List<Animal> ani = new ArrayList<Dog>()// não dar ser por que o compilador verifica tipo em tempo de compilação.

Obs: Assuma que Animal é superClasse de Dog.

Espero ter ajudado!!!


public static void teste(Animal [] ani){
  

   ani[2] = new Cat();// isso vai compilar ???

}

public static void main(String ... args){

       Animal[] cat = new Dog[3];
       teste(cat);
}

Daniel isso vai compilar, vai causar um exceção ???

Muito boa a questão Raff.

Eu já esperava que compilaria sem problemas. Só não esperava o exception em tempo de execução.

[]s
Gunnar

verdade esses tipo de questoes são muito boas mesmo !Obrigado !

Compila e dá erro de execução.

Isso foi um dos erros da definição da linguagem Java, e foi infelizmente copiado no .NET; na verdade, esse problema foi percebido, e evitado na definição de generics. Com generics tal problema não pode ocorrer:

import java.util.*;

interface Animal {}
class Cat implements Animal {}
class Dog implements Animal {}

class TesteArrays {
    
public static void teste(Animal [] ani){

        // Isto compila mas provoca uma exceção ao rodar:
        // 'Exception in thread &quot;main&quot; java.lang.ArrayStoreException: Cat'
        ani[2] = new Cat();// isso vai compilar ???

    
}
    

public static void main(String... args){

       
        Animal[] cat = new Dog[3];
       
        teste(cat);

        // isto compila...
        List&lt;? extends Animal&gt; dogs = new ArrayList&lt;Dog&gt;(); 
        // mas (que seria uma tradução de ani[2] = new Cat()) 
        // não compila...
        dogs.set (2, new Cat()); 
        // nem isto (que seria uma tradução direta de
        // Animal[] cat = new Dog[3];) compila.
        List&lt;Animal&gt; animals = new ArrayList&lt;Dog&gt;(); // isto nem compila
    }

}

Valeu Raff, pela explicação agora sim deu pra entender legal, neste seu caso com o thingol respondeu:

public static void teste(Animal [] ani){   
     
 
   ani[2] = new Cat();// isso vai compilar ???   
  
}   
  
public static void main(String ... args){   
  
       Animal[] cat = new Dog[3];   
       teste(cat);   
}  

Compila normalmente, mas quando ele vai tentar insntanciar a posicão 2 do vetor com new Cat dará erro de excecução, pois ele só aceita referencias de Dog.

Certo??

Att

É isso ai daniel :smiley:

[quote=thingol]Compila e dá erro de execução.

Isso foi um dos erros da definição da linguagem Java, e foi infelizmente copiado no .NET; na verdade, esse problema foi percebido, e evitado na definição de generics. Com generics tal problema não pode ocorrer:

[code]
import java.util.*;

interface Animal {}
class Cat implements Animal {}
class Dog implements Animal {}

class TesteArrays {

public static void teste(Animal [] ani){

    // Isto compila mas provoca uma exceção ao rodar:
    // 'Exception in thread &quot;main&quot; java.lang.ArrayStoreException: Cat'
    ani[2] = new Cat();// isso vai compilar ???

}

public static void main(String… args){

    Animal[] cat = new Dog[3];
   
    teste(cat);

    // isto compila...
    List&lt;? extends Animal&gt; dogs = new ArrayList&lt;Dog&gt;(); 
    // mas (que seria uma tradução de ani[2] = new Cat()) 
    // não compila...
    dogs.set (2, new Cat()); 
    // nem isto (que seria uma tradução direta de
    // Animal[] cat = new Dog[3];) compila.
    List&lt;Animal&gt; animals = new ArrayList&lt;Dog&gt;(); // isto nem compila
}

}
[/code][/quote]
thingol por que isso não compila??

eu achava que isso compilaria sim pois a classe dog implementa a interface Animal…
Estou errado ? ou Certo ?

Amigo, eu escrevi no código acima:

        // isto compila...  
        List&lt;? extends Animal&gt; dogs = new ArrayList&lt;Dog&gt;();  

Ou seja, o código compila direitinho.

[quote=Raff][quote=thingol]Compila e dá erro de execução.

Isso foi um dos erros da definição da linguagem Java, e foi infelizmente copiado no .NET; na verdade, esse problema foi percebido, e evitado na definição de generics. Com generics tal problema não pode ocorrer:

[code]
import java.util.*;

interface Animal {}
class Cat implements Animal {}
class Dog implements Animal {}

class TesteArrays {

public static void teste(Animal [] ani){

    // Isto compila mas provoca uma exceção ao rodar:
    // 'Exception in thread &quot;main&quot; java.lang.ArrayStoreException: Cat'
    ani[2] = new Cat();// isso vai compilar ???

}

public static void main(String… args){

    Animal[] cat = new Dog[3];
   
    teste(cat);

    // isto compila...
    List&lt;? extends Animal&gt; dogs = new ArrayList&lt;Dog&gt;(); 
    // mas (que seria uma tradução de ani[2] = new Cat()) 
    // não compila...
    dogs.set (2, new Cat()); 
    // nem isto (que seria uma tradução direta de
    // Animal[] cat = new Dog[3];) compila.
    List&lt;Animal&gt; animals = new ArrayList&lt;Dog&gt;(); // isto nem compila
}

}
[/code][/quote]
thingol por que isso não compila??

eu achava que isso compilaria sim pois a classe dog implementa a interface Animal…
Estou errado ? ou Certo ?

[/quote]

compila sim.
<? extends Animal> aceita qualquer coisa do tipo Animal ou suas subclasses. Em outras palavras, qualquer coisa que SEJA um Animal.

A única observação é que quando você utiliza <? extends Animal> você não pode adicionar elementos ao collection, a não ser que utilize <? super Dog>. Ai você pode adicionar elementos ao collection, já que você sabe de antemão o que vai ser adicionado. Outra restrição é que esses elementos tem que ser do tipo DOG (no meu exemplo). Se for de qualquer outro tipo dá erro de compilação.

[code]
class Animal{
}

class Dog extends Animal{}

public class G1{

public static void main(String[] args){
	List&lt;? super Dog&gt; l = new ArrayList&lt;Object&gt;();
	//l.add(new Animal());
	//l.add(new Object());
	l.add(new Dog());
		
}

}[/code]

[]s
Gunnar

foi mal thingol não vi o que tu escreveu :smiley:

valew Gunnar