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