Problemas parecidos: Array vs Generics

 
 

import java.util.List;

import java.util.ArrayList;

 
 

public class Teste {

public static void main(String[] args) {

Animal[] animals = new Dog[2];

animals[0] = new Dog();

animals[1] = new Cat();
// não podemos inserir um Cat em um array de Dog. Repare que o objeto é do tipo Dog[] e o problema se da porque a variável que o referencia é do tipo Animal[]. Isso é perfeitamente possível no Java porém incorre neste problema de runtime (ArrayStoreException)

 
 

}

}

 
 

class Animal{}

class Dog extends Animal {}

class Cat extends Animal {}

  

import java.util.List;

import java.util.ArrayList;

 
 

public class Teste {

public static void main(String[] args) {

List<Dog> dogs = new ArrayList<Dog>();

dogs.add(new Dog());

dogs.add(new Dog());

 
 

List<? extends Animal> animals = dogs;

for(Animal animal : animals)

System.out.println(animal);

 
 

animals.add(new Cat());
// a regra do Generics não permite inserir um Cat em uma lista genérica de Dog. Se não houver essa linha de adição na declaração ‘animals’ não teríamos erro de compilação. Esta é a maneira que Generics protege de inserirmos coisas erradas em uma coleção.

}

}

 
 

class Animal{}

class Dog extends Animal {}

class Cat extends Animal {}

javac:

Exception in thread “main” java.lang.ArrayStoreException: Cat

at Teste.main(Teste.java:8)

javac:

Teste.java:14: cannot find symbol

animals.add(new Cat());

^

symbol: method add(Cat)

location: interface List<CAP#1>

where CAP#1 is a fresh type-variable:

CAP#1 extends Animal from capture of ? extends Animal

1 error

 
 

 
 

Generics é mais protegido que Array pois impede a compilação antes do objeto ser inserido. (veja quadro 2)

 
 

Nos exemplos que seguem abaixo o quadro 1 e o quadro 2, são bastante parecidos em termos de executar as mesmas operações. Porém, o quadro 1, que realiza a operação com array, não protege no caso da passagem da referência animals como parâmetro da função doStuff. Um possível problema de uso de arrays pode ser demonstrado no quadro 3.

 
 

Já no quadro 2, que realiza a operação com generics, a passagem do parâmetro dogs para a função doStuff() não é permitida, garantindo então a segurança do código antes que o erro contido no quadro 3 seja cometido, ou seja, passar um Cat para uma array do tipo de Dog.

 
 

 
 

(1) maior liberdade com arrays

mport java.util.List;

import java.util.ArrayList;

 
 

public class Teste {

public static void main(String[] args) {

Animal[] animals = new Dog[2];

animals[0] = new Dog();

 
 

doStuff(animals);

 
 

}

public static void doStuff(Animal[] animals){}

}

 
 

class Animal{}

class Dog extends Animal {}

class Cat extends Animal {}

(2) maior segurança com generics

import java.util.List;

import java.util.ArrayList;

 
 

public class Teste {

public static void main(String[] args) {

List<Dog> dogs = new ArrayList<Dog>();

dogs.add(new Dog());

dogs.add(new Dog());

 
 

doStuff(dogs);

}

public static void doStuff(List<Animal> animals){}

}

 
 

class Animal{}

class Dog extends Animal {}

class Cat extends Animal {}

javac: Ok !!!

javac:

Teste.java:10: method doStuff in class Teste cannot be applied to given types

doStuff(dogs);

^

required: List<Animal>

found: List<Dog>

1 error

(3) array permite adições perigosas

import java.util.List;

import java.util.ArrayList;

 
 

public class Teste {

public static void main(String[] args) {

Animal[] animals = new Dog[2];

animals[0] = new Dog();

 
 

doStuff(animals);

 
 

}

public static void doStuff(Animal[] animals){

animals[1] = new Cat(); // animals refere-se a Dog[] no heap.

}

}

 
 

class Animal{}

class Dog extends Animal {}

class Cat extends Animal {}

(4) generics não permite adicões perigosas

import java.util.List;

import java.util.ArrayList;

 
 

public class Teste {

public static void main(String[] args) {

List<Dog> dogs = new ArrayList<Dog>();

dogs.add(new Dog());

dogs.add(new Dog());

 
 

doStuff(dogs);

 
 

 
 

}

public static void doStuff(List<? extends Animal> animals){

// NÃO SE PODE ADICIONAR NADA A animals

// animals.add(new Cat()) // proibido !!!

// animals.add(new Dog()) // proibido !!!

// animals.add(new Animal()) // proibido !!!

}

}

 
 

class Animal{}

class Dog extends Animal {}

class Cat extends Animal {}

javac:

Exception in thread “main” java.lang.ArrayStoreException: Cat

at Teste.doStuff(Teste.java:13)

at Teste.main(Teste.java:9)

javac: Ok … as adições proibidas estão comentadas //

 
 

 
 

Esta entrada foi publicada em Generics com as etiquetas . ligação permanente.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s