Java – Should a Method Return Collection or ImmutableCollection?

apicollectionsjavareturn-type

When writing an API in Java, returning an immutable collection of some sort, I've got the option of returning Collection (or List, Map, etc) from the method, or guava's ImmutableCollection (or ImmutableList, ImmutableMap, etc):

private final ImmutableMap<> _immutableMap = ...

public Collection<T> getValues() {
    return _immutableMap.values();
}

or

public ImmutableCollection<T> getValues() {
    return _immutableMap.values();
}

Which is better?

Setting the return value as ImmutableCollection constrains me to use that exact type forever more, so that I can't swap out _immutableMap for my own immutable type later on that returns, say, an immutable view of the values that isnt an ImmutableCollection (constructing one requires copying the values, and I can't subclass it to provide an immutable view of a mutable collection).

But there is benefit to people calling the method to see the return value is actually immutable, and have the add and remove methods marked as deprecated, rather than trying to add or remove items and have it fail at runtime.

Generally, I like to return the most-specific interface type from a method, so that I can change the underlying implementation later on if necessary without breaking contract. But there is benefit to callers returning an ImmutableCollection, at the cost of constraining future development of the method and causing future possible performance problems due to copying all the values into an ImmutableCollection rather than providing an immutable view.

Best Answer

I would normally recommend using the more abstract types (Collection, List etc) in this case.

Reasons:

  • It provides more flexibility to return a different concrete type in the future. Somebody may come up with a better ImmutableList than Guava, for example.
  • Collection, List etc are more familiar to users.
  • It avoids a dependency on Guava in your public API. Avoiding external dependencies is generally good, use the standard APIs wherever you can.

If you are happy to commit to always using Guava collections, or if this is just an internal API that won't be widely used by different people then I guess it doesn't matter so much.

P.S. if your concern is signalling to the user that the return value is immutable, I would suggest finding another way to communicate this (annotations, documentation, method naming etc.). The Java type system isn't really designed for communicating arbitrary facts about types (some more sophisticated type systems attempt this, but it's still a research topic)

Related Topic