I'm writing functional-style static helper methods acting as operators for a generic abstraction (say Iterable<T>
), and I'm a bit confused about when I should use wildcards. What are the correct, most type-safe and simplest method signatures in the following cases, and why?
public static int size(Iterable<?> source)
vs.
public static <T> int size(Iterable<T> source)
public static <T> Iterable<T> take(Iterable<T> source, int count)
vs.
public static <T> Iterable<T> take(Iterable<? extends T> source, int count)
public static boolean elementsEqual(Iterable<?> first, Iterable<?> second)
vs.
public static <T> boolean elementsEqual(Iterable<T> first, Iterable<T> second)
vs.
public static <T> boolean elementsEqual(Iterable<? extends T> first, Iterable<? extends T> second)
public static <T> int size(Iterable<T> source)
is equivalent to
public static int size(Iterable<?> source)
as long as you don't need to refer to T
in the method implementation. I'd err towards the ?
, just because it reduces clutter.
public static <T> Iterable<T> take(Iterable<? extends T> source, int count)
is the more general, and it should work in both cases, so I'd go ahead with that one.
public static boolean elementsEqual(Iterable<?> first, Iterable<?> second)
is appropriate because Object.equals(Object)
doesn't have a narrowed signature.
(Guava provides many of these methods; you could use that as a reference if you like. Disclosure: I contribute to Guava.)