So you have a class containing a List
field (it should be final
, since you don't intend to assign to it), and you want to allow callers to add to the List
, but not be able to replace it.
You could either provide a getter for the list:
public List<E> getMyList() {
return myList;
}
Or provide a method to add to that list:
public void addToMyList(E e) {
myList.add(e);
}
Both are valid design decisions, but which you use will depend on your use case. The first option gives callers direct access to the List
, effectively making it public. This is useful when users will be modifying and working with the list repeatedly, but can be problematic as you can no longer trust the List
is in any sort of reliable state (the caller could empty it, or reorder it, or even maliciously insert objects of a different type). So the first option should only be used when you intend to trust the caller.
The second option gives the caller less power, because they can only add one element at a time. If you want to provide additional features (insertion, add-all, etc.) you'll have to wrap each operation in turn. But it gives you more confidence, since you can be certain the List
is only being modified in ways you approve of. This latter option also hides (encapsulates) the implementation detail that you're using a List
at all, so if encapsulation is important for your use case, you want to go this way to avoid exposing your internal data structures, and only expose the behavior you want to grant to callers.