A colleague recently asked me how to deep-clone a Map and I realized that I probably have never used the clone() method- which worries me.
What are the most common scenarios you have found where you need to clone an object?
I assume you are referring to Object.clone() in Java. If yes, be advised that Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer. I believe you can safely use Object.clone() on primitive type arrays, but apart from that you need to be judicious about properly using and overriding clone. You are probably better off defining a copy constructor or a static factory method that explicitly clones the object according to your semantics.
Most commonly, when I have to return a mutable object to a caller that I'm worried the caller might muck with, often in a thread-unfriendly way. Lists and Date are the ones that I do this to most. If the caller is likely to want to iterate over a List and I've got threads possibly updating it, it's safer to return a clone or copy of it.
Actually, that brings up something I'm going to have to open up another question for: copy constructors or clone? When I did C++, we ALWAYS did a copy constructor and implemented clone with it, but FindBugs does not like it if you implement your clone using a copy constructor.
When I need to make a duplicate of something to modify the duplicate without impacting the original, and of course in this scenario deep cloning (only) will suffice. I've had to do this on a system where I would clone a domain class instance, apply the user's changes, and then perform a comparison of the two for the user to verify their changes.
The Object.clone() method doesn't specify whether the copy of a subclass is a deep or shallow copy, it's completely dependent of the specific class. The Object.clone() method itself does a shallow copy (copies internal state of the Object class), but subclasses must override it, call super.clone(), and copy their internal state as needed (shallow or deep).
It does specify some conventions, which you may or not follow. For (a.getClass() == a.clone().getClass()) to return true, super.clone() should be called instead of simply 'new Subclass()', since super.clone() presumably would correctly instantiate the class of this object (even in subclasses), and copy all internal state, including private fields, which couldn't be copied by subclasses using a copy constructor, due visibility rules. Or you would be forced to expose a constructor that shouldn't be exposed, for better encapsulation.
Example:
//simple clone
class A implements Cloneable {
private int value;
public A clone() {
try {
A copy = (A) super.clone();
copy.value = this.value;
return copy;
} catch (CloneNotSupportedException ex) {}
}
}
//clone with deep and shallow copying
class B extends A {
Calendar date;
Date date;
public B clone() {
B copy = (B) super.clone();
copy.date = (Calendar) this.date.clone(); // clones the object
copy.date = this.date; // copies the reference
return copy;
}
}
Deep copy is usually used when dependent objects are mutable (like Calendar), and the copy must be completely independent of the original.
When dependent objects are immutable (like Date), sharing the same instance usually isn't an issue, and a shallow copy may be sufficient.
When using Object.clone() you must follow some rules, but they are simple enough to be understandable. Probably the most difficult part is correctly defining how deep you should copy into your object graph. A logical issue, not a language issue, that is.
I have used Object.clone() in a Spring webflow application to check what has changed when a user edits / enters data on a form for auditing purposes.
At the beginning of the flow, I call the clone method which was implemented on the form backing object used in the spring webflow and save the instance of the clone to the user session. Once the user has completed editing data on the html form and pressed the save button I compare the new values bound to the backing object to the cloned value to determine what data the user has changed.
This worked well and was really easy to implement, I haven't really experienced any issues with cloning in Java.
Related
I would like to have some guarantee that instances of some particular class Content is only accessed by its "owner", and if another object wants the same Content it needs to take a deep copy. Coming from C++ I would achieve that using a unique_ptr, is there anything similar in Java?
Currently I am resolving this by just keeping the Content private everywhere I keep one and paying attention to creating a new Content (the constructor implements the deep copy mechanism) on a getContent. But I have no means of enforcing possible other users of the Content class to follow the same pattern, it's easy to forget. It would be nicer if it could take care of itself somehow, like not being copyable.
I realize that it goes somewhat against the spirit of the language, but in some cases I think it's justified. For example, if Content represents some stream of data that is modified even by reading it. I thought, if not in the core language, maybe there is some #interface for compile-time checking or a way of creating one?
Edit: The idea is that the owner can modify the object freely, before or after taking copies, and if someone takes a deep copy, they can modify theirs (not affecting the original), so making the Content immutable is a bit too harsh (unless I'm misunderstanding what that implies).
There are a couple of common strategies here:
Privacy with defensive copying
In this strategy, you'd have the owner have a private reference to the content, and if it's appropriate for it to give out copies of that content, to do so via a defensive copy:
class Owner {
private Content content;
// ...unnecessary detail omitted...
public Content getContent() {
return new Content(this.content);
}
}
The Cloneable interface can sometimes be useful here.
Immutable objects
The other common strategy is to use immutable objects (e.g., ensure that Content, once instantiated, cannot be modified). Then you don't care who has a reference to the content, since they cannot change it.
No there isn't.
Once you have established a reference to an object, there's absolutely nothing you can do to stop someone form assigning another reference to that object via that established reference.
Java programmers get round this by making objects immutable (see java.lang.String). Then you ought not give two hoots about who else is referring to a particular instance.
You can declare the class Content as Immutable by doing this:
Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
If the instance fields include references to mutable objects, don't allow those objects to be changed
Here is a java official doc: https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
Java does not have something like that. There are some language elements that can help with such requirements:
Enums that have only one constant; to be used as "built-in" singletons
Methods in Collections to create immutable copies of collections
And of course, you can make all fields in your class final; so they get initialized only during construction time; to prevent later changes
But as Java is also missing a const concept, you can partially work around such things. Like in:
class Foo {
private final List<Bar> bars = new ArrayList<>();
doesn't mean that instances of Foo will be immutable - as you still can add/remove elements to that list owned by Foo.
Similar; given
List<Foo> root = ...
List<Foo> immutableCopy = Collections.unmodifiableList(root);
one can still change that immutableCopy ... by messing up root.
This question already has answers here:
clone() vs copy constructor vs factory method?
(10 answers)
Closed 8 years ago.
clone method vs copy constructor in java. which one is correct solution. where to use each case?
Clone is broken, so dont use it.
THE CLONE METHOD of the Object class
is a somewhat magical method that does
what no pure Java method could ever
do: It produces an identical copy of
its object. It has been present in the
primordial Object superclass since the
Beta-release days of the Java
compiler*; and it, like all ancient
magic, requires the appropriate
incantation to prevent the spell from
unexpectedly backfiring
Prefer a method that copies the object
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Read more
http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
Have in mind that clone() doesn't work out of the box. You will have to implement Cloneable and override the clone() method making in public.
There are a few alternatives, which are preferable (since the clone() method has lots of design issues, as stated in other answers), and the copy-constructor would require manual work:
BeanUtils.cloneBean(original) creates a shallow clone, like the one created by Object.clone(). (this class is from commons-beanutils)
SerializationUtils.clone(original) creates a deep clone. (i.e. the whole properties graph is cloned, not only the first level) (from commons-lang), but all classes must implement Serializable
Java Deep Cloning Library offers deep cloning without the need to implement Serializable
clone() was designed with several mistakes (see this question), so it's best to avoid it.
From Effective Java 2nd Edition, Item 11: Override clone judiciously
Given all of the problems associated with Cloneable, it’s safe to say
that other interfaces should not extend it, and that classes
designed for inheritance (Item 17) should not implement it. Because of
its many shortcomings, some expert programmers simply choose never to
override the clone method and never to invoke it except, perhaps, to
copy arrays. If you design a class for inheritance, be aware that if
you choose not to provide a well-behaved protected clone method, it
will be impossible for subclasses to implement Cloneable.
This book also describes the many advantages copy constructors have over Cloneable/clone.
They don't rely on a risk-prone extralinguistic object creation mechanism
They don't demand unenforceable adherence to thinly documented conventions
They don't conflict with the proper use of final fields
They don't throw unnecessary checked exceptions
They don't require casts.
All standard collections have copy constructors. Use them.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
Keep in mind that the copy constructor limits the class type to that of the copy constructor. Consider the example:
// Need to clone person, which is type Person
Person clone = new Person(person);
This doesn't work if person could be a subclass of Person (or if Person is an interface). This is the whole point of clone, is that it can can clone the proper type dynamically at runtime (assuming clone is properly implemented).
Person clone = (Person)person.clone();
or
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Now person can be any type of Person assuming that clone is properly implemented.
See also: How to properly override clone method?. Cloning is broken in Java, it's so hard to get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.
Great sadness: neither Cloneable/clone nor a constructor are great solutions: I DON'T WANT TO KNOW THE IMPLEMENTING CLASS!!! (e.g. - I have a Map, which I want copied, using the same hidden MumbleMap implementation) I just want to make a copy, if doing so is supported. But, alas, Cloneable doesn't have the clone method on it, so there is nothing to which you can safely type-cast on which to invoke clone().
Whatever the best "copy object" library out there is, Oracle should make it a standard component of the next Java release (unless it already is, hidden somewhere).
Of course, if more of the library (e.g. - Collections) were immutable, this "copy" task would just go away. But then we would start designing Java programs with things like "class invariants" rather than the verdammt "bean" pattern (make a broken object and mutate until good [enough]).
In C++ a getter & setter for a private data member is very useful due to the ability to control mutability via a const return value.
In Java, if I understand correctly (please correct me if I am mistaken), specifying final on a getter doesn't work that way. Once the caller received the data member reference through the getter, it can modify it, despite it being private...
If that's the case (and please correct me if I have a gross misconception here), why not declare the data member public and simplify things?
Making immutable return values in java is a matter of either returning already immutable objects types (such as String) or returning a copy for non-immutable objects.
Sample 1 - Already immutable object
public String getValue() {
return value;
}
Sample 2 - Collection of already immutable objects
public List<String> getValues() {
return new ArrayList<String>(values);
}
Sample 3 - Non-immutable object
public Complex getComplex() {
return complex.clone();
}
Sample 4 - Collection of non-immutable objects
public List<Complex> getComplex() {
List<Complex> copy = new ArrayList<Complex>(complexs.size());
for (Complex c : complexs)
copy.add(c.clone());
return copy;
}
Sample 3 and 4 are for conveniance based on that the complex type implements the Cloneable interface.
Furthermore, to avoid subclasses overriding your immutable methods you can declare them final. As a side note, the builder pattern is typically useful for constructing immutable objects.
If you want your class to be immutable (i.e. having only final fields and getters) you must be sure that the values you return are immutable as well. You get this for free when returning Strings and built-in primitives, however some extra steps are necessary for other data types:
wrap collections with immutable decorators or defensively copy them before returning from a getter
make a copy of Date and Calendar
Only return immutable objects or defensively clone them. This also applies to objects in collections.
Note that if you defensively copy a collection, the client can view or modify the copy, but this does not affect the original collection:
return new ArrayList<Foo>(foos);
On the other hand if you wrap the original collection, the client is able to see all the changes that were introduced to the collection after the wrapper was created, but trying to change the contents of the wrapper will result in runtime exception:
return Collections.unmodifiableList(foos);
The bottom line is: Foo has to be immutable as well, otherwise the collection is immutable, but the client code can still modify members of the collection. So the same rules apply to Foo.
If that's the case (and please correct me if I have a gross misconception here), why not declare the data member public and simplify things?
Because:
you might wish to store mutable data inside an object and only provide immutable (read-only) view of the data (like wrapping collections)
you can change the implementation in the future, get rid of the field and for instance compute the value on the fly.
If you want to return an immutable view of a mutable standard container (eg list), then you should take a look at the Collections library:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html
It provides some useful wrappers such as unmodifiableMap and unmodifiableList. That way you don't have to make a wasteful copy. Of course, if the elements of the list are mutable, then this won't help as much -- there's no easy way in Java to get "deep" immutability. Of course, the same is true in C++ -- e.g., if you have a const vector of pointers to Foo objects, then the Foo objects themselves can still be modified (because const doesn't propagate across pointers).
If that's the case (and please correct me if I have a gross misconception here), why not declare the data member public and simplify things?
First of all, the JavaBeans spec. requires you to provide getters (and setters for mutable properties).
Second, getters might enable you to add some logic, e.g. one getter might actually decide what to return (e.g. if the property is null return something differenc). If you didn't have getters in the first place you'd have more trouble to add such logic later on. With getters you'd just change the method without touching the callers.
why not declare the data member public and simplify things?
Because information hiding makes it easier to manage and maintain a complex codebase. If the data members are private, you can change representation and behavior in one class, rather than throughout a large codebase.
Once the caller received the data member reference through the getter, it can modify it, despite it being private...
To clarify, a caller cannot modify a data member returned from a getter. It might be able to modify an object to which the data member points.
If this is a problem, and you're providing access through a getter, you can return an immutable instance, or a defensive copy.
The setter is also valuable for controlling modification to a referenced object. You can make a defensive copy in the setter.
This question already has answers here:
clone() vs copy constructor vs factory method?
(10 answers)
Closed 8 years ago.
clone method vs copy constructor in java. which one is correct solution. where to use each case?
Clone is broken, so dont use it.
THE CLONE METHOD of the Object class
is a somewhat magical method that does
what no pure Java method could ever
do: It produces an identical copy of
its object. It has been present in the
primordial Object superclass since the
Beta-release days of the Java
compiler*; and it, like all ancient
magic, requires the appropriate
incantation to prevent the spell from
unexpectedly backfiring
Prefer a method that copies the object
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Read more
http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
Have in mind that clone() doesn't work out of the box. You will have to implement Cloneable and override the clone() method making in public.
There are a few alternatives, which are preferable (since the clone() method has lots of design issues, as stated in other answers), and the copy-constructor would require manual work:
BeanUtils.cloneBean(original) creates a shallow clone, like the one created by Object.clone(). (this class is from commons-beanutils)
SerializationUtils.clone(original) creates a deep clone. (i.e. the whole properties graph is cloned, not only the first level) (from commons-lang), but all classes must implement Serializable
Java Deep Cloning Library offers deep cloning without the need to implement Serializable
clone() was designed with several mistakes (see this question), so it's best to avoid it.
From Effective Java 2nd Edition, Item 11: Override clone judiciously
Given all of the problems associated with Cloneable, it’s safe to say
that other interfaces should not extend it, and that classes
designed for inheritance (Item 17) should not implement it. Because of
its many shortcomings, some expert programmers simply choose never to
override the clone method and never to invoke it except, perhaps, to
copy arrays. If you design a class for inheritance, be aware that if
you choose not to provide a well-behaved protected clone method, it
will be impossible for subclasses to implement Cloneable.
This book also describes the many advantages copy constructors have over Cloneable/clone.
They don't rely on a risk-prone extralinguistic object creation mechanism
They don't demand unenforceable adherence to thinly documented conventions
They don't conflict with the proper use of final fields
They don't throw unnecessary checked exceptions
They don't require casts.
All standard collections have copy constructors. Use them.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
Keep in mind that the copy constructor limits the class type to that of the copy constructor. Consider the example:
// Need to clone person, which is type Person
Person clone = new Person(person);
This doesn't work if person could be a subclass of Person (or if Person is an interface). This is the whole point of clone, is that it can can clone the proper type dynamically at runtime (assuming clone is properly implemented).
Person clone = (Person)person.clone();
or
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Now person can be any type of Person assuming that clone is properly implemented.
See also: How to properly override clone method?. Cloning is broken in Java, it's so hard to get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.
Great sadness: neither Cloneable/clone nor a constructor are great solutions: I DON'T WANT TO KNOW THE IMPLEMENTING CLASS!!! (e.g. - I have a Map, which I want copied, using the same hidden MumbleMap implementation) I just want to make a copy, if doing so is supported. But, alas, Cloneable doesn't have the clone method on it, so there is nothing to which you can safely type-cast on which to invoke clone().
Whatever the best "copy object" library out there is, Oracle should make it a standard component of the next Java release (unless it already is, hidden somewhere).
Of course, if more of the library (e.g. - Collections) were immutable, this "copy" task would just go away. But then we would start designing Java programs with things like "class invariants" rather than the verdammt "bean" pattern (make a broken object and mutate until good [enough]).
as far as I understand, getters/setters should always make copies, in order to protect the data.
However, for many of my classes, it is safe to have the getter return a reference to the property asked for, so that the following code
b = a.getB();
b.setC(someValue);
actually changes the state of object a. If I can prove that it is OK for my class, is it good practice to implement the getter this way? Should the user then be notified of this, for example in the Javadoc? I think that this would break the implementation-hiding paradigm, so, should I always assume that the state of a did not change, and make a call to the setter
b = a.getB();
b.setC(someValue);
a.setB(b);
Thanks in advance
S
There's a good argument in your above example that since A is maintaining a reference to B, A should look after B, and not hand it out but manipulate it on your behalf. Otherwise you can argue that you're breaking encapsulation (since A reveals it has a reference to B), and ideally objects should do things for you, rather than export their contents such that you can manipulate them.
Having said all that, the above is certainly not an uncommon practise and often a pragmatic choice.
When you expose an object via get(), you have three options:
expose the actual object
make a defensive copy
expose an object that wraps the original, but prohibits modification. e.g. you can wrap the original object in a restricted interface. See (for example) Collections.unmodifiableCollection() which wraps the original collection (and doesn't copy it) but provides an interface that doesn't permit modification.
Whatever you do, you should document it in the interface (and hence in the Javadoc). Otherwise you're at liberty to change it later, and dependent code can easily break.
Well, the setC violates the Law of Demeter, so I don't think I'd call it a best practice. ("Law" is a bit strong - for instance, it's generally not applied to fluent interfaces.)
That said, getters should not always make copies IMHO. Doing a deep clone can be expensive. There are other options, such as immutable objects.
And, realistically, there are pragmatic considerations.
But I'd err on the side of TMI (too much information) in the JavaDoc.
A further option not yet mentioned is to expose the object via an immutable interface. Obviously this isn't fool-proof as the calling code could always downcast the object into the mutable version, but it avoids any overhead in wrapping the object or creating a copy.
I usually take this approach if I'm writing an API that I'm likely to use myself or within my programming team; i.e. where I know "clients" are going to be good citizens!
// Immutable interface definition.
public interface Record {
String getContent();
}
// Mutable implementation of Record interface.
public class MutableRecord implements Record {
private final String content;
public MutableRecord(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
// API that only exposes the object via its Record interface.
public class MyApi {
private final MutableRecord mutableRecord;
public Record getRecord() {
return mutableRecord;
}
}
You will get copying wrong before you know it! And then you have a real bug, not a potential one.
Therefore, if you trust the client code, don't bother about it.
This is highly academic and I personally never had a problem with it. I also immediately turn the check off in FindBugs (Java) for example...
And unless there is a problem, who reads JavaDoc and the like anyway? Anybody out there?