6

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?

  • I don't get it but I'm a bit of a simpleton in Java. I see one thing that requires more code and one thing that requires less, and both are equally generic, yes? Of course maybe the implementation of the interface shouldn't factor in so much, but aren't both effectively saying that they accept a List of whatever? Is there more to this than syntactical preference? The second version makes sense to me for an API if it is somehow more flexible and not just nicer-looking, since it makes sense to create APIs to leave as much breathing room as possible for different implementations. – user204677 Jan 31 '18 at 17:25
  • .... while preserving compatibility. – user204677 Jan 31 '18 at 17:31
4

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 a List 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.