13.8. Parameterized Types and Inheritance

You can define a class as a subclass of a class type that is an instance of a generic type. For example, you could derive a new class from type LinkedList<Person> or from type BinaryTree<String>. Methods and fields will be inherited from the base class in the usual way. However, you can encounter complications because of the way the compiler translates methods that involve type arguments into bytecodes, so let's first understand that process.

Each method that involves parameters and/or the return value type specified by a type argument is translated by the compiler to a method with the same name, but with the type of each parameter whose type is a type variable replaced by its leftmost bound. Where the type of the return value is a type variable, then that, too, is replaced by its leftmost bound. Casts are inserted in the body of the translated method where necessary to produce the actual types required. You'll find that an example will help clarify this.

Earlier you saw a version of the LinkedList<> type defined as:

public LinkedList<T extends Object & Serializable> {
  public void addItem(T item) {
    // Code for the method...
  }

  // More code for the type definition...
}

If you define an object of type LinkedList<String>, notionally the addItem() method for the object is like this:

public void addItem(String item) {
    // Code for the method...
  }

However, the compiler will translate the addItem() method to the following:

public void addItem(Object ...

Get Ivor Horton's Beginning Java™ 2, JDK™ 5th Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.