Closed GoogleCodeExporter closed 9 years ago
I prefer not to use arrays at all :-)
If you use arrays, you should also do the same for the getters.
Original comment by r.spilker
on 22 Oct 2013 at 4:06
BTW, it is strange that it complains about arrays, and not about all the other
mutable types...
I think in a way this is a duplicate of an issue that is more general: provide
a way to make a safe copy for getters and setters.
Original comment by r.spilker
on 22 Oct 2013 at 4:16
Roel and I have discussed this problem before and it's not going to get a fix
until the heat death of the universe, probably. Our conclusions on this topic
are as follows:
* This issue exists for _ALL_ mutable types. Arrays, Lists (unless
ImmutableList / list wrapped in Collections.unmodifiable and the upstream no
longer holds a reference to the inner list. I'm foreshadowing how complicated
this is), stringbuilder/buffer, j.u.Date, and a million other things. There is
no list of which built-in types are mutable and which are immutable and even if
we signed up to the work of making this list, that doesn't cover the millions
of external libraries used in the java community.
* Even if we found an extensible way to make this list, for example with an
@Immutable annotation we'd have to scan for (which would involve resolution,
not something we can do for @Setter and co anytime soon, but that's a separate
issue), the community doesn't have a singular definition for what this means
exactly and java in general is not capable of understanding it as a concept.
ALL objects are in the end distinguishable and not side-effect-free, in the
sense that they all have unique identity hash codes and they can all be locked
on via 'synchronized', so in theory I have to make defensive copies of
absolutely every last object ever, every time said object crosses any method
boundary, just to ensure that truly the object ref I stored in my private field
is 100% guaranteed safe from interference. Anything less is trying to decide
where to draw the line. That's asking for trouble: Discussion on moving the
line will ensue, and those who have a different interpretation of where the
line should be will probably think lombok also drew it closer to where they
think it should be, and as a result, will misunderstand the feature. Another
problematic consideration: Is java.io.File immutable?
* Even if we somehow crossed that problem by committing to some definition of
what @Immutable means, that doesn't really help. The immutable-ness of objects
is often a runtime property and not a typed property. For example, when
wrapping a list via Collections.unmodifiable, there's no way to use type
introspection to figure this out. Even if you use runtime type checking to
figure out the list.getClass() is that mystery inner private class that
Collections makes to make unmodifiableList work, we have no guarantee that all
references to the wrapped list have since disappeared. We could decide to
always create safety copies for everything unless the type system can prove to
us that it is impossible for the object to change, but this is highly
impractical; there are LOTS of java classes that just aren't set up for this,
and in that vein we would have to treat __EVERY__ non-final class as something
we MUST safe-copy. The amount of pointless copying that would be done by
lombok-generated code would not be acceptable.
* ... and even if we somehow solved that problem, there's no type-agnostic code
that can create copies of things. We can build into lombok how to make copies
of arrays, how to make copies of the various built-in collections APIs, and
various other things. But what about everything else? How do I copy a JButton?
This also highlights another issue: Often you don't _WANT safe copies;
sometimes you're passing (via getter and/or setter) a mutable object around
with the express intent that this thing IS mutated on by code smeared out
across various classes and instances. Yes, many feel that this concept as a
development model is going to result in bug-ridden hard to maintain code, but
there's literally billions of lines of code out there that work this way. We
can't just cover our eyes and try to pretend all java code is highly
'functional' and almost entirely built around immutables.
* ... and even if we somehow solved every single problem named so far, it is
highly impractical. Take arrays; if you are using arrays, presumably efficiency
is important (if it is not, you should be using List instead). We have to make
a copy BOTH on set AND on get, and if all of the JVM was built like this, you'd
be producing many GBs of garbage a nanosecond, the CPU would be blitting bytes
95% of the time, all your CPU memory caches would run out and need refreshing
every other CPU cycle, and in general everything would slow to an impractical
crawl. Pragmatically speaking, 'safe copy everything' does not work; you have
to just use unsafe copies (and write your code so that it isn't a problem), and
only use safe copying on public system boundaries, such as your library's
public API.
That's 5 insurmountable issues that all need to be solved before we can begin
to add support for the idea of safe copying, especially implicit safe copying.
I can foresee a far future where lombok will let you explicitly specify a copy
strategy both for 'in' (setters, constructors) and 'out' (getters) behaviour,
but one where we just safe-copy all arrays without prompting? I'd love to see
the day when java has arrived at the state where that's feasible, but if I'm
being realistic, I have to file this under 'never gonna happen'.
I'm just as bummed about that as you, no doubt :(
Original comment by reini...@gmail.com
on 23 Jan 2014 at 7:17
Thanks for this complete answer !
Original comment by william....@gmail.com
on 24 Jan 2014 at 11:04
BTW, for you information, I try to use (a little) this project
https://github.com/verhas/immutator who handle immutability in java
Original comment by william....@gmail.com
on 24 Jan 2014 at 11:06
Original issue reported on code.google.com by
william....@gmail.com
on 17 Oct 2013 at 9:19