Re: AspectJ: solution to Java's repetitiveness?
jhc0033@gmail.com wrote:
I'm afraid it doesn't have the right semantics. I wrote a test
You are correct, the default clone() implementation is a shallow copy only.
That would motivate overriding the method, and perhaps implementing Cloneable.
application to check this. Suppose I want a tree of 3D vectors. I also
want to be able to copy these trees so that I can modify the original
with impunity:
If I read this correctly, you want clone() to do a deep copy, right?
public class Vec3D implements Cloneable {
double x, y, z;
}
Slight mistake here. According to the Javadocs for Cloneable:
By convention, classes that implement this interface should
override Object.clone (which is protected) with a public method.
import java.util.ArrayList;
public class Vec3DTree implements Cloneable {
Vec3D leaf;
ArrayList<Vec3DTree> branches;
Vec3DTree() { // trivial default CTOR - more repetitiveness
What do you mean by repetitiveness here? And why is it a problem?
leaf = new Vec3D();
branches = new ArrayList<Vec3DTree>();
}
protected Object clone() throws CloneNotSupportedException {
Same comment here: should override clone() to be public.
return super.clone();
and to do more than merely call the super version.
}
}
public class Vec3DTreeMain {
public static void main(String[] args) {
Vec3DTree t1 = new Vec3DTree();
t1.leaf.x = 1;
t1.branches.add(new Vec3DTree());
t1.branches.get(0).leaf.y = 2;
try {
Vec3DTree t2 = (Vec3DTree) t1.clone();
With a covariant return type, you could really skip this cast.
// modify original
t1.branches.get(0).leaf.z = 3;
}
catch(CloneNotSupportedException e) {
System.out.println("oops");
}
}
}
The line that modifies the original in the try block also modifies the
"copy". So, Object::clone didn't clone the branches. I probably have
Of course not. This is documented behavior. Again, the Javadocs:
this method performs a "shallow copy" of this object,
not a "deep copy" operation.
to write stuff by hand, like overriding Object::clone in Vec3D and
Well, yeah. As the Javadocs suggest:
By convention, the object returned by this method should be independent of
this object (which is being cloned). To achieve this independence, it may be
necessary to modify one or more fields of the object returned by super.clone
before returning it. Typically, this means copying any mutable objects that
comprise the internal "deep structure" of the object being cloned and
replacing the references to these objects with references to the copies. If a
class contains only primitive fields or references to immutable objects, then
it is usually the case that no fields in the object returned by super.clone
need to be modified.
perhaps subclassing ArrayList and overriding Object::clone there as
well.
Not needed. You override clone() in Vec3DTree. This is a requirement,
really, for classes that you declare Cloneable.
Consider this equivalent C++
Nope. C++ is not Java.
--
Lew