To be clear, it seems like a nice boiler-plate avoidance technique (which Java could always use more of). But you're implying that there's some other significant underlying problem this solves and I don't see it.
Also, unmodifiableCollection doesn't make the collection you pass in immutable; it creates a new object through which you can access it as long as you don't modify it. Anybody holding a reference to the original object can still change the object.
I think you can even somewhat break the collection by changing objects inside it if doing that changes their hashcode (for sets and dictionaries, such a change may have to reinsert the item in the collection to make sure that you can still retrieve it)
If you weren't using this library, you could achieve something similar with, e.g.,
someImmutableSet = Collections.unmodifiableSet(new HashSet<E>(someSet));
I think this library really is about making immutable objects accessible, i.e., taking away the boiler plate. Hand-writing immutable (and potentially mutable) implementations on top of interfaces for a whole set of DTOs is super annoying.In order for a class to be immutable, all its fields need to be be immutable and final. Immutability got to be recursive.
Also, in Java, the class should be final, otherwise nothing prevents anyone from extending it and pass a mutable data structure instead of the immutable one you'd expect
Edit : added the "in java", as we could imagine another language where immutable doesn't require objects to be final.
If I have:
private final Map<String, String> map = new HashMap<>();
I cannot say map = someOtherMap;, but I can still say map.put("key", "value");.
Plus, you can't statically know if the collection you're passed is immutable or not. Trying to modify it will just blow up at runtime.
It wouldnt work. If MutableList<E> extends ImmutableList<E> then every MutableList is also an ImmutableList. This way you can be forced to return a MutableList, but not an ImmutableList.
They're not really comparable.
This is code generation for builders, getters, etc. The idea is that you write less of the boilerplate that you'd write if you were rolling your own immutable POJOs.
Plus, unless I'm mis-reading the docs, it also handles certain collection types transparently. (Which obviously just throwing final on a property won't do.)