Question

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?

  • Checking properties:

public static int size(Iterable<?> source)

vs.

public static <T> int size(Iterable<T> source)

  • Transforming:

public static <T> Iterable<T> take(Iterable<T> source, int count)

vs.

public static <T> Iterable<T> take(Iterable<? extends T> source, int count)

  • Combining:

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)

Was it helpful?

Solution

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.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top