Consider the following classes:
public class AnimalHouse<E> { private E animal; public void setAnimal(E x) { animal = x; } public E getAnimal() { return animal; } } public class Animal{ } public class Cat extends Animal { } public class Dog extends Animal { }
For the following code snippets, identify whether the code:
Question:
AnimalHouse<Animal> house = new AnimalHouse<Cat>();
Answer: Fails to compile. AnimalHouse<Cat>
and AnimalHouse<Animal>
are not compatible types, even though Cat
is a subtype of Animal
.
Question:
AnimalHouse<Cat> house = new AnimalHouse<Animal>();
Answer: Fails to compile. Same as 1a: AnimalHouse<Cat>
and AnimalHouse<Animal>
are not compatible types, even though Cat
is a subtype of Animal
.
Question:
AnimalHouse<?> house = new AnimalHouse<Cat>(); house.setAnimal(new Cat());
Answer: Fails to compile. While the first line is acceptable it is OK to define an instance of unknown type the compiler doesn't know the type of animal stored in house
so the setAnimal
method cannot be used.
Question:
AnimalHouse house = new AnimalHouse(); house.setAnimal(new Dog());
Answer: Compiles with a warning. The compiler doesn't know what type house
contains. It will accept the code, but warn that there might be a problem when setting the animal to an instance of Dog
.
Using a generic type as a raw type might be a way to work around a particular compiler error, but you lose the type checking that generics provides, so it is not recommended.
Exercise: Design a class that acts as a library for the following kinds of media: book, video, and newspaper. Provide one version of the class that uses generics and one that does not. Feel free to use any additional APIs for storing and retrieving the media.
Answer:
Non-Generic Version
import java.util.List; import java.util.ArrayList; public class Library { private List resources = new ArrayList(); public void addMedia(Media x) { resources.add(x); } public Media retrieveLast() { int size = resources.size(); if (size > 0) { return (Media)resources.get(size - 1); } return null; } } interface Media { } interface Book extends Media { } interface Video extends Media { } interface Newspaper extends Media { }
Generic Version
import java.util.List; import java.util.ArrayList; public class Library<E extends Media> { private List<E> resources = new ArrayList<E>(); public void addMedia(E x) { resources.add(x); } public E retrieveLast() { int size = resources.size(); if (size > 0) { return resources.get(size - 1); } return null; } }