Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java 101: The next generation: The essential Java language features tour, Part 1

Java programming with assertions and generics

  • Print
  • Feedback

Page 5 of 9

North
South
East
West

Bounding type parameters

The E in Set<E> is an example of an unbounded type parameter because you can pass any actual type argument to E. For example, you can specify Set<Marble>, Set<Employee>, or Set<String>.

Sometimes, you'll want to restrict the types of actual type arguments that can be passed to a type parameter. For example, perhaps you want to restrict a type parameter to accept only Employee and its subclasses.

You can limit a type parameter by specifying an upper bound, which is a type that serves as the upper limit on the types that can be passed as actual type arguments. Specify the upper bound via reserved word extends followed by the upper bound's type name.

For example, class Employees<E extends Employee> restricts the types that can be passed to Employees to Employee or a subclass (e.g., Accountant). Specifying new Employees<Accountant> would be legal, whereas new Employees<String> would be illegal.

You can assign more than one upper bound to a type parameter. However, the first bound must always be a class, and the additional bounds must always be interfaces. Each bound is separated from its predecessor by an ampersand (&). Check out Listing 6.

Listing 6. GenDemo.java (version 2)

import java.math.BigDecimal;

import java.util.Arrays;

abstract class Employee
{
   private BigDecimal hourlySalary;
   private String name;

   Employee(String name, BigDecimal hourlySalary)
   {
      this.name = name;
      this.hourlySalary = hourlySalary;
   }

   public BigDecimal getHourlySalary()
   {
      return hourlySalary;
   }

   public String getName()
   {
      return name;
   }

   public String toString()
   {
      return name+": "+hourlySalary.toString();
   }
}

class Accountant extends Employee implements Comparable<Accountant>
{
   Accountant(String name, BigDecimal hourlySalary)
   {
      super(name, hourlySalary);
   }

   public int compareTo(Accountant acct)
   {
      return getHourlySalary().compareTo(acct.getHourlySalary());
   }
}

class SortedEmployees<E extends Employee & Comparable<E>>
{
   private E[] employees;
   private int index;

   SortedEmployees(int size)
   {
      employees = (E[]) new Employee[size];
      int index = 0;
   }

   void add(E emp)
   {
      employees[index++] = emp;
      Arrays.sort(employees, 0, index);
   }

   E get(int index)
   {
      return employees[index];
   }

   int size()
   {
      return index;
   }
}

public class GenDemo
{
   public static void main(String[] args)
   {
      SortedEmployees<Accountant> se = new
SortedEmployees<Accountant>(10);
      se.add(new Accountant("John Doe", new BigDecimal("35.40")));
      se.add(new Accountant("George Smith", new BigDecimal("15.20")));
      se.add(new Accountant("Jane Jones", new BigDecimal("25.60")));

      for (int i = 0; i < se.size(); i++)
         System.out.println(se.get(i));
   }
}

Listing 6's Employee class abstracts the concept of an employee that receives an hourly wage. This class is subclassed by Accountant, which also implements Comparable<Accountant> to indicate that Accountants can be compared according to their natural order, which happens to be hourly wage in this example.

  • Print
  • Feedback

Resources
  • Download the source code for this article.
  • Read Angelika Langer's Java Generics FAQs for a wealth of information and perspective about generics in the Java language.
  • For students of the Java language and its controversies, Langer's "Und erstanding the closures debate" (JavaWorld, June 2008) compares the three initial proposals for adding closures, or lambda expressions, to the Java language in Java 7.
  • See "Java Reflection: Generics" (Jakob Jenkov, Jenkov.com) for further discussion about reflection with generics and special cases where it is possible to access generics information at runtime.
  • More from Java 101: The next generation:
  • More about the Java Collections Framework on JavaWorld: