ArrayList data = new ArrayList();
data.add( "Might work" );
This fragment will create a raw ArrayList
that contains references to Object
.
Recall that Object
is at the top of the class hierarchy, so all objects have Object
as an ancestor.
So the array data
in the above can hold references to any type of object.
This is how Java 1.0 worked, and this feature has been kept so that old programs still work.
But you should not use it in new programs.
Programmers can create a generic class. Pick a name for a the class and a name for the type variable (usually a single capital letter). Put the type variable inside angle brackets <> after the class name. In the code for the class use the type variable instead of a specific type.
Here is the non-generic Node
class from the previous chapters:
public class Node { private int value; private Node next; public Node ( int val ) { value = val; next = null; } public int getValue() { return value; } public Node getNext() { return next; } public void setValue( int val ) { value = val; } public void setNext( Node nxt ) { next = nxt; } public String toString() { return "" + value ; } }
This Node
is not generic.
It can only directly contain a primitive int
value.
Here is a generic Node
:
public class GenericNode<E> { private E value; private GenericNode<E> next; public GenericNode( E val ) { value = val; next = null; } public E getValue() { return value; } public GenericNode<E> getNext() { return next; } public void setValue( E val ) { value = val; } public void setNext ( GenericNode<E> nxt ) { next = nxt; } public String toString() { return "" + value; } }
The type variable E
says where the particular type you specify in a constructor should go.
Inspect the following use of a constructor:
GenericNode<String> names = new GenericNode<>();
This in effect replaces the type variable T
with the class name String
:
public class GenericNode { private String value; private GenericNode String next; public GenericNode( String val ) { value = val; next = null; } public String getValue() { return value; } public GenericNode String getNext() { return next; } public void setValue( String val ) { value = val; } public void setNext ( GenericNode String nxt ) { next = nxt; } public String toString() { return "" + value; } }
The type variable can be any identifier. But it is conventional to use single capital letters, often "E" for Element or "T" for Type. This visually separates type variables from other variables and makes programs easier to read.
The constructor for GenericNode
in the above code starts out as:
public GenericNode( E val )
Should this be:
public GenericNode<E>( E val )
?