Your implementation:
public A addData(int data){ A newA = new A(this); newA.bOb.add(data); // <--- bOb is mutable return newA; }
A bOb is being changed, so if you expose any direct access to bOb, it can be changed. (Since you're not exposing anything about bOb, the scenario doesn't make sense.)
Hints:
Collections.emptyList() returns an immutable list. Collections.unmodifiableList() returns an immutable shallow-copy of a given list.
Consider this "safer" implementation:
import java.util.*; public final class A<T>{ //T must also be immutable (String, integer, char, ...) private final List<T> list; public A(){ this.list = Collections.emptyList(); } public A(List<T> list){ this.list = Collections.unmodifiableList(list); } public A<T> addData(T data){ List<T> shallowCopy = new ArrayList<T>(this.list); shallowCopy.add(data); return new A<T>(shallowCopy); } public List<T> getItems() { return this.list; } }