Java Reference
In-Depth Information
}
}
The changes from the previous version of the generic type are the bold lines. Notice how you use the
extends
keyword regardless of whether the type parameter bound is a class or an interface. Of course, this
applies only to bounds for type parameters in a generic type. Where the generic type itself implements an
interface, you use the
implements
keyword, and where it extends a class you use the
extends
keyword,
just as you would for an ordinary class type. Of course, the
ListItem
inner class must also implement the
Serializable
interface because you need
ListItem
objects to be serializable.
Where you need to specify a type parameter that has several bounds, you use a special notation. You put
&
between the type names that are bounds following the
extends
keyword. Here's how that looks:
class MyType<T extends FancyClass & Serializable & MyInterface> {
// Code defining the generic type...
}
The parameter for the
MyType<>
generic type has three bounds: the
FancyClass
class and the interfaces
Serializable
and
MyInterface
. All type arguments for
T
to the
MyType<T>
parameterized type must ex-
tend the
FancyClass
class and implement both the
Serializable
and the
MyInterface
interfaces.
Let's see if the serializable
LinkedList<>
generic type works.
TRY IT OUT: Using Parameter Bounds in a Generic Type
This example exercises the last version of the
LinkedList<>
generic type by serializing a list of integers
and then deserializing it:
import static java.lang.Math.random;
import java.nio.file.*;
import java.io.*;
public class TrySerializableLinkedList {
public static void main(String[] args) {
Path file = Paths.get("D:/Junk/Numbers.bin");
try {
// Create parent directory if it doesn't exist
Files.createDirectories(file.getParent());
} catch(IOException e) {
System.err.println("Error creating directory: " +
file.getParent());
e.printStackTrace();
}
// Create a list containing random integers
LinkedList<Integer> numbers = new LinkedList<>();
for(int i = 0 ; i < 10 ; ++i) {