Here's something interesting I only just discovered about generics in Java.
You're probably well aware that you can write a generic method like this:
public static <T> Collection<T> commonElements(Collection<T> c1, Collection<T> c2) {
Collection<T> results = new ArrayList<T>();
for (T t : c1) {
if (c2.contains(t)) {
results.add(t);
}
}
return results;
}
This is a simple method that returns a list of elements that are common between two collections. This compiler automatically determines the type of the returned collection based on the type of the input parameters c1 and c2.
Here's an example of how it might be used (assume the commonElements() method is in a class called
Example)
Collection<Integer> c1 = Arrays.asList( new Integer[] { 1, 2, 3});
Collection<Integer> c2 = Arrays.asList( new Integer[] { 2, 3, 4});
Collection<Integer> common = Example.commonElements(c1, c2);
Ok, nothing new so far.
So here's what I only just discovered. You can also write generic methods that determine the return type based on what you're assigning the result to. For example:
public static <T> List<T> createEmptyList() {
return new ArrayList<T>();
}
This method will create an empty list of whatever type you assign it to. So you could call the method like this:
List<Integer> listOfIntegers = Example.createEmptyList();
So long as the compiler can determine the type of variable that you're assigning to, then all is well. There is one interesting edge case where this doesn't quite work. In the example below, the compiler can't determine the type and will complain with a "type mismatch" error.
boolean condition = true; List<String> listOfStrings = (condition ? Example.createEmptyList() : null);
To fix it, you need to prefix the method call with the type like so:
boolean condition = true; List<String> listOfStrings = (condition ? Example.<String>createEmptyList() : null);
I only learned about this feature of generics when I accidentally discovered that Java 5 introduced a new static method
to the java.util.Collections class called emptyList(). It serves a similar purpose to the
old EMPTY_LIST field, but caters for generic collections.