implement any methods. In this case, any instances of the class become valid instan‐
ces of the interface. Java code can check whether an object is an instance of the
interface using the instanceof operator, so this technique is a useful way to provide
additional information about an object.
The java.io.Serializable interface is a marker interface of this sort. A class
implements the Serializable interface to tell ObjectOutputStream that its instan‐
ces may safely be serialized. java.util.RandomAccess is another example:
java.util.List implementations implement this interface to advertise that they
provide fast random access to the elements of the list. For example, ArrayList
implements RandomAccess , while LinkedList does not. Algorithms that care about
the performance of random-access operations can test for RandomAccess like this:
// Before sorting the elements of a long arbitrary list, we may want
// to make sure that the list allows fast random access. If not,
// it may be quicker make a random-access copy of the list before
// sorting it. Note that this is not necessary when using
List l = ...; // Some arbitrary list we're given
if ( l . size () > 2 && !( l instanceof RandomAccess )) l = new ArrayList ( l );
sortListInPlace ( l );
As we will see later, Java's type system is very tightly connected to the names that
types have—an approach called nominal typing . A marker interface is a great exam‐
ple of this—it has nothing at all except a name.
One of the great strengths of the Java platform is the standard library that it ships. It
provides a great deal of useful functionality—and in particular robust implementa‐
tions of common data structures. These implementations are relatively simple to
develop with and are well documented. The libraries are known as the Java Collec‐
tions, and we will spend a big chunk of Chapter 8 discussing them. For a far more
complete treatment, see the topic Java Generics and Collections by Maurice Naftalin
and Philip Wadler (O'Reilly).
Although they were still very useful, the earliest versions of the collections had a
fairly major limitation, however. This limitation was that the data structure (often
called the container ) essentially hid the type of the data being stored in it.
Data hiding and encapsulation is a great principle of object-
oriented programming, but in this case, the opaque nature of
the container caused a lot of problems for the developer.
Let's kick off the section by demonstrating the problem, and showing how the intro‐
duction of generic types can solve it, and make life much easier for Java developers.