The JavaTM Tutorial
Previous Page Lesson Contents Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Classes and Inheritance

Answers to Questions and Exercises: Generics

Questions

Question 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:
  1. fails to compile
  2. compiles with a warning
  3. generates an error at runtime
  4. none of the above (compiles and runs without problem)
Question 1a. AnimalHouse<Animal> house = new AnimalHouse<Cat>();
Answer 1a: 1. fails to compile
AnimalHouse<Cat> and AnimalHouse<Animal> are not compatible types, even though Cat is a subtype of Animal.

Question 1b. AnimalHouse<Cat> house = new AnimalHouse<Animal>();
Answer 1b: 1. fails to compile
Same as 1a: AnimalHouse<Cat> and AnimalHouse<Animal> are not compatible types, even though Cat is a subtype of Animal.

Question 1c. AnimalHouse<?> house = new AnimalHouse<Cat>();
             house.setAnimal(new Cat());
Answer 1c: 1. 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 1d. AnimalHouse house = new AnimalHouse();
             house.setAnimal(new Dog());
Answer 1d: 2. 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

Exercise 1. Write an example that sorts a set of predefined strings based on string length. Use the version of the Collections.sort method that takes a Comparator parameter.
Answer 2. Here are two versions an example called FoodSort:
import java.util.*;

public class FoodSort {
    static class CompareFoodStrings
                  implements Comparator<String> {
        //This Comparator sorts based on string length.
        public int compare(String o1, String o2) {
            return o1.length() - o2.length();
        }
    }
    public static void main(String[] args) {
        String[] foodStrings = {"cheese pizza", "aloo gobi", "samosa",
				"enchilada", "lasagna", "minestrone",
				"manicotti", "ziti", "burrito", "chocolate"};
        List<String> foods = Arrays.asList(foodStrings);
        Comparator<String> comp = new CompareFoodStrings();
        Collections.sort(foods, comp);
        for (String s : foods) {
            System.out.println(s);
        }
    }
}
This second version of FoodSort implements the comparator as an anonymous inner class:
import java.util.*;

public class FoodSort {
    public static void main(String[] args) {
        String[] foodStrings = {"cheese pizza", "aloo gobi", "samosa",
				"enchilada", "lasagna", "minestrone",
				"manicotti", "ziti", "burrito", "chocolate"};
        List<String> foods = Arrays.asList(foodStrings);
        //This Comparator sorts based on string length.
        Collections.sort(foods, new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        });
        for (String s : foods) {
            System.out.println(s);
        }
    }
}


Previous Page Lesson Contents Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.