3

I would like to define a class that has an ArrayList as one of its parameters. The entries of the ArrayList should be final. In my understanding, simply declaring the ArrayList attribute of the class as 'final' will not achieve this, because it just means that the reference to this list is final. How can I declare that the entries of the list are to be treated as 'final'?

 public class MyClass{

    private final ArrayList<Double> classAttributeWithFinalValues; // the entries of the list can still be changed


    public MyClass(ArrayList<Double> classAttribute){
        this.classAttributeWithFinalValues = classAttribute;
    }
 }
fedorSmirnov
  • 701
  • 3
  • 9
  • 19
  • I'm happy to be corrected, but I think your best bet is simply to make the class type immutable (i.e. all public final fields). – Diego Martinoia Feb 01 '16 at 12:15
  • You can prevent reassignments of the collection by making it final, and you can prevent add/remove by using J8 Unmodifiable collections, but I don't think anything can stop you using setters on the objects, lest not having setters :) – Diego Martinoia Feb 01 '16 at 12:16
  • 2
    First, you should use a `List` rather than an `ArrayList`. Second, since `Double` is already immutable, it is sufficient to what a **copy** of the given `List` in an `UnmodifyableList` - `this.list = Collections.unmodifiableList(new ArrayList<>(list))`. – Boris the Spider Feb 01 '16 at 12:17

1 Answers1

0

ArrayLists are always mutable, if you want the list to be Immutable, you can either create your own list implementation that doesn't allow add() operations after being built, or simply use Guava's ImmutableList. The list is built using a builder class, and once built, it cannot be modified:

ImmutableList<String> myList =  ImmutableList.<String>builder().add("a").add("b").build();
myList.add("c"); //Throws UnsupportedOperationException

If, on the other hand, you want only the entries to be immutable, not the map itself, then that depends on the objects you put in the list. The Double you use in your code snippet is already immutable. But if you want to make mutable objects immutable, you'll have to either wrap them in a wrapper that doesn't allow access to setter methods, or make sure to return copies of the original items stored.

Malt
  • 28,965
  • 9
  • 65
  • 105
  • Whilst this does answer the question, it is a link-only answer. It does not contain any code to explain how to use this. Moreover, when recommending the inclusion of a (really rather large) third party library, I would expect some justification as to why a JDK solution (defensive copy and unmodifiable collection) is inappropriate. – Boris the Spider Feb 01 '16 at 12:21
  • This does not answer the question imho. Op is asking how to make the ENTRIES immutable, not the collection (i.e. add/remove). Though it may be the question is ambiguous and that's what he means. – Diego Martinoia Feb 01 '16 at 12:56