6 ms·
What's the advantage of that as opposed to the 'standard' java way of doing immutable via 'final'?
by iwwr 11y ago
What's the advantage of that as opposed to the 'standard' java way of doing immutable via 'final'?
- atinoda-kestrel 11y ago> What's the advantage of that as opposed to the 'standard' java way of doing immutable via 'final'? 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.)
- dikaiosune 11y agoMy IDE (IntelliJ) does a lot of the writing of immutable POJOs for me :). The builders are a bit different for sure, but I don't see what's wrong with having an object that is only "mutable" in the construction phase.
- quarterto 11y agoThese aren't immutable variables, they're immutable (i.e. persistent) data structures. You can't directly change the objects themselves; instead, "setters" create a new copy of the object.
- dikaiosune 11y agoPerhaps I haven't had enough coffee yet, but could you explain how an immutable data structure is any different than an object whose class definition is all final? If you can't change any property of the object, wouldn't that be the same as what this annotation does? 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.
- saryant 11y agoJava doesn't have immutable collections in its standard library. If if a java.util.* collection is declared final, you can still modify its contents.
- dikaiosune 11y agoDerp, for whatever reason I was thinking of an object as the data structure in this case. Thanks for clarifying!
- impl 11y agoActually, it does, but they don't have explicit types. See java.util.Collections.unmodifiableCollection(...), etc.
- Someone 11y agoThat still doesn't work all the way down. The objects you get out of the collection remain as mutable as when they were inserted. 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)
- impl 11y agoRight, but this project doesn't solve that problem, either. It wraps the underlying collection in a builder to make it less easy to access, but it doesn't appear that it places any additional restrictions on the types of members or collection elements (from the generated code on their site anyway). 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.
- _asummers 11y agofinal in Java is only immutable references. 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");.
- mbreese 11y agoBut you can wrap that Map with Collections.unmodifiableMap() for an immutable version.
- saryant 11y agoNot quite. If the original collection is modified, the "immutable" view will reflect that change. 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.
- _asummers 11y agoIndeed, but there is no way to reflect that in the return type, besides the JavaDoc of course. If you try and modify it later, you'll get a runtime exception, which is a pretty crappy thing. One of the things I dislike most about the Collections API is that Mutable interfaces are not extensions of Immutable interfaces with just the addition of modifiers. I should be forced to say that I'm returning a Mutable version of a data structure in my return type.
- dorgo 11y ago> is that Mutable interfaces are not extensions of Immutable interfaces with just the addition of modifiers. I should be forced to say that I'm returning a Mutable version of a data structure in my return type. 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.
- _asummers 11y agoFair point, you're absolutely correct. Admittedly I haven't given this a TON of thought, because it seems like something that can't be added anymore. Maybe the interfaces should be siblings, but since Java doesn't have a disjoint type, you might run into problems if something says it implements both MutableList and ImmutableList. Not sure if Java's type system is strong enough to deal with this problem.