Trail: Learning the Java Language
Lesson: Generics
Home Page > Learning the Java Language > Generics

Answers to Questions and Exercises: Generics

Questions

  1. 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:

    • fails to compile,
    • compiles with a warning,
    • generates an error at runtime, or
    • none of the above (compiles and runs without problem.)
    1. 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.

    2. 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.

    3. 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.

    4. 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.

Exercises

  1. 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;
        }
    }
    
« PreviousTOC

Problems with the examples? Try Compiling and Running the Examples: FAQs.
Complaints? Compliments? Suggestions? Give us your feedback.

Previous page: Questions and Exercises: Generics