|
|
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
Page 7 of 9
George Smith: 15.20
Jane Jones: 25.60
John Doe: 35.40
You cannot specify a lower bound for a generic type parameter. To understand why I recommend reading Angelika Langer's Java Generics FAQs on the topic of lower bounds, which she says "would be confusing and not particularly helpful."
Let's say you want to print out a list of objects, regardless of whether these objects are strings, employees, shapes, or some other type. Your first attempt might look like what's shown in Listing 7.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenDemo
{
public static void main(String[] args)
{
List<String> directions = new ArrayList<String>();
directions.add("north");
directions.add("south");
directions.add("east");
directions.add("west");
printList(directions);
List<Integer> grades = new ArrayList<Integer>();
grades.add(new Integer(98));
grades.add(new Integer(63));
grades.add(new Integer(87));
printList(grades);
}
static void printList(List<Object> list)
{
Iterator<Object> iter = list.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
It seems logical that a list of strings or a list of integers is a subtype of a list of objects, yet the compiler complains when you attempt to compile this listing. Specifically, it tells you that a list-of-string cannot be converted to a list-of-object, and similarly for a list-of-integer.
The error message you've received is related to the fundamental rule of generics:
For a given subtype x of type y, and given G as a raw type declaration, G<x> is not a subtype of G<y>.
According to this rule, although String and java.lang.Integer are subtypes of java.lang.Object, it's not true that List<String> and List<Integer> are subtypes of List<Object>.
Why do we have this rule? Remember that generics are designed to catch type-safety violations at compile time, which is helpful:
without generics, you are much more likely to be called in to work at 2 a.m. because your Java program has thrown a ClassCastException and crashed!
As a demonstration, let's assume that List<String> was a subtype of List<Object>. If this was true, you might end up with the following code:
List<String> directions = new ArrayList<String>();
List<Object> objects = directions;
objects.add(new Integer());
String s = objects.get(0);
This code fragment creates a list of strings based on an array list. It then upcasts this list to a list of objects (which
isn't legal, but for now just pretend it is). Next, it adds an integer to the list of objects, which violates type safety.
The problem occurs in the final line, which throws ClassCastException because the stored integer cannot be cast to a string.
Without generics, your only option to prevent such a violation of type safety would be to pass an object of type List<Object> to the printList() method in Listing 7, which wouldn't be very useful. With generics, however, you can use wildcards to solve the problem, as shown in Listing 8.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenDemo
{
public static void main(String[] args)
{
List<String> directions = new ArrayList<String>();
directions.add("north");
directions.add("south");
directions.add("east");
directions.add("west");
printList(directions);
List<Integer> grades = new ArrayList<Integer>();
grades.add(new Integer(98));
grades.add(new Integer(63));
grades.add(new Integer(87));
printList(grades);
}
static void printList(List<?> list)
{
Iterator<?> iter = list.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
In Listing 8 I use a wildcard (the ? symbol) in place of Object in printList()'s parameter list and body. Because this symbol stands for any type, it's legal to pass List<String> and List<Integer> to this method.
Compile Listing 8 (javac GenDemo.java) and run the application (java GenDemo). You should observe the following output:
java.util.concurrent.
java.time classes you're most likely to need.