#Why not use Object#clone? how is it bad? is ArrayType#clone also unsafe?

1 messages · Page 1 of 1 (latest)

young dagger
#
Object o = ...;
o.clone(); // considered bad
Object[] os = { ... };
os.clone(); // some people say bad and some say good
novel deltaBOT
#

<@&987246399047479336> please have a look, thanks.

limber juniper
#

Cloneable is problematic. You must implement clone on your type. The default behaviour is then to shallowly and blindly copy the values of all member fields - unless a superclass decides to override clone() to get some measure of deep cloning, in which case there's no established model for sub-class cloning (but the clone-method won't know that). And the cloning bypasses constructors. So it's easy to introduce bugs by breaking model invariants.

For arrays, clone is well-defined so generally this is considered fine.

upbeat relic
# young dagger ```java Object o = ...; o.clone(); // considered bad Object[] os = { ... }; os.c...

On top of what Talden said
clone needs Cloneable interface, yet it is a marker interface, for whatever reason, and clone is a method that any object has, this is a terrible design, because it means you can't know at compile time if an object is cloneable, you also can't clone a generic object or an object where you have its interface because of this
on top of that, clone is quite literaly black magic, the way it works is alien to java, magically creating an object and init its fields without calling its constructor, by just calling super.clone(), this shouldn't make any sense in java, but that's how it works

balmy pelican
#

and now the better alternative: a copy constructor

formal herald
#

Array clone method still makes sense for performance reasons, although I prefer to use other methods

formal herald
#

so I recommend avoiding the clone method, although you can still use it if you want, but don't implement it in your classes

formal herald
upbeat relic
formal herald
upbeat relic
#

but so are the other copy methods

formal herald
#

Yea true

wind pine
upbeat relic
formal herald
formal herald
pulsar wind
#

It means the JIT can't/won't attempt to rejigger it. It's a black box.

limber juniper
#

One of the optimisations is to perform escape analysis after inlining. The intrinsic for clone observes the identity so I suspect that in places where you use clone, the clone source is no longer a candidate for scalarisation. Now scalarisation doesn't happen nearly as much as we'd hope but it is possible that cloning could prevent an optimisation. I don't recall seeing any array scalarisation but since there is optimisation to constify bounds (observe that a particular array is always size N) I imagine this optimisation limitation could also apply to array cloning (less likely IMO however).

JIT is serious black-magic.

pulsar wind
#

I recall the array clone performance issue revolves around it being able to skip the zero-ing out phase since it will be overwriting those locations immediately. I saw (within 6mos) someone had done benchmarks recently on which is faster for copying arrays and I think the consensus was just use Arrays.copy.