lishunli / projectlombok

Automatically exported from code.google.com/p/projectlombok
0 stars 0 forks source link

Array are stored directly #594

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.declare a byte[] value
2.add a @Setter

What is the expected output? What do you see instead?

output is 
public void setValue(byte[] value) {
 this.value = value;
}

I prefer (and Sonar too :P)

public void setValue(byte[] value) {
  if(value == null) { 
    this.value = value;
  } else { 
   this.value = Arrays.copyOf(value, value.length); 
  } 
}

Please provide any additional information below.

Arrays.copyOf() works for all types of Array :)
(http://stackoverflow.com/questions/11580948/sonar-violation-security-array-is-s
tored-directly)

Original issue reported on code.google.com by william....@gmail.com on 17 Oct 2013 at 9:19

GoogleCodeExporter commented 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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
Thanks for this complete answer !

Original comment by william....@gmail.com on 24 Jan 2014 at 11:04

GoogleCodeExporter commented 9 years ago
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