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;
}
}