Effective Java provides 2 ways to implement swap
:
// Two possible declarations for the swap method
public static <E> void swap(List<E> list, int i, int j);
public static void swap(List<?> list, int i, int j);
Then, Mr. Bloch says:
Which of these two declarations is preferable, and why? In a public
API, the second is better because it's simpler. You pass in a list—any
list—and the method swaps the indexed elements. There is no type
parameter to worry about. As a rule, if a type parameter appears only
once in a method declaration, replace it with a wildcard.
It appears that swapNoWildCard
could be used rather than the swap
and swapHelper
method. Mr. Bloch explains the reasoning for using the 2nd signature above.
public static <E> void swapNoWildcard(List<E> list, int i, int j) {
E e = list.set(j, list.get(i));
list.set(i, e);
}
public static void swap(List<?> list, int i, int j) {
swapHelper(list, i, j);
}
private static <E> void swapHelper(List<E> list, int i, int j) {
E e = list.set(j, list.get(i));
list.set(i, e);
}
However, is this debatable given the fact that swapNoWildCard
is almost half the # of lines of code compared to implementing the other 2 methods?
Why is it so useful to leave out the type parameter?
Best Answer
In good software design what you want, or better yet in an idealized world you must, have an interface which communicates intent. Taking away the type parameter of the
List
expressed that intent clearly. You're telling the caller "I'm only interested in acting on aList
and nothing more." This is why the second is better than the first.As an aside, the reason that the second method requires two function calls is that Java does not have type inference so you are forced to declare an
E
to capture one of the swapped values.