Is it possible to deep copy an Object out of the box? i.e. any other way than coding a clone function manually.
Cloning does not necessarily perform a deep copy. In fact, the default implementation of Object.clone() creates a shallow copy.
If the object's closure consists of objects that implement Serializable or Externalizable, you can use ObjectOutputStream and ObjectInputStream to create a deep copy ... but it is expensive.
The cloning library is another option, but my initial reading of the code is that it relies on the class of every object in the graph providing a no-argument constructor. Then it will then patch the resulting object to have a copy of the original object's state. This process might have undesirable side-effects, depending on what the no-args constructor actually does.
In short, I don't think there is a universal solution.
I suggest to use java.lang.reflect.
java.lang.Class expose all fields and allows reading public fields and calling public methods.
Only the private field without accessors can't be cloned.
I briefly looked at the cloning library code. It does what Serialization does that is get the graph of the object internal and instead of writing to file, it writes to a memory location = which is the clone of the object. So although its faster than Serialization, its certainly doing the same thing.
Related
I need to deep clone a object which has some non-serialization objects as members in Java.
Can you provide some reference what can i use for this ?
Note:
Please provide reference to some standard library of java. I don't want to use any unapproved/private package or library.
Or some code pointers how can i clone the object ?
In the absence of standardisation of values in Java, I strongly suggest avoiding any dodgy reflection/code generation scheme.
If you can, changing to immutable types removes the need to copy.
Other than that, just write the code neatly. If there are a lot of collections, writing map methods will help to avoid the palaver of Streams (and be faster).
When you make a Java class which contains another class as a field and want to make a setter for the class, how do you decide if it should be deep copied or shallow copy?
You would want to use a deep copy if you don't want changes in the copy to be reflected in the original object. Alternatively, if you don't plan to make such changes, or don't care if they are reflected as such, then you might use a shallow copy, since they are generally cheaper to create. The Wikipedia article entitled Object copy explains the difference between the two in greater detail.
From this Artima article on clone vs copy constructor:
Object's clone method is very tricky. It's based on field copies, and
it's "extra-linguistic." It creates an object without calling a
constructor. There are no guarantees that it preserves the invariants
established by the constructors. There have been lots of bugs over the
years, both in and outside Sun, stemming from the fact that if you
just call super.clone repeatedly up the chain until you have cloned an
object, you have a shallow copy of the object.
What does Joshua Bloch mean by extra-linguistic?
He means something like "outside of the scope of Java".
Specifically in Java the "correct" way to create a new object is by using that Object's constructor. Many class writers rely on this assumption and code logic into their constructors - things like input validation or anything else you want to guarantee at construction time - this is what he calls "invariants established by the constructors". But cloning bypasses this basic constraint and creates a memory copy without invoking the constructor - hence it is "extra linguistic".
Technically, so does serialization.
Probably the fact that it isn't implemented in Java but it has a native in the Object class.
The extra-linguistic object creation mechanisms (meaning other than calling or chaining constructors) are:
cloning
serialization
reflection
btye-code generation
In Java, which is faster:
Cloning an Object, then passing it to multiple listeners assuming the cloned object contains nothing more complicated than nested arrays, primitives and Strings
Using Streams to pass data through from one object to another?
I would guess cloning is faster, because:
When you clone you create an object from another by instantiating it and it attributes.
When you use streams you serialize an object and deserialize it (whereas Java also have to create an instance of the object). So when you use streams you have the overhead of serializing the objects.
Of course the implementation of clone() should not do something unusual which increases time to copy the objects. To clone an object with arrays, primitives and Strings should not consume so much time.
Cloning will be faster, assuming the implementation of clone() is reasonably sane.
If you think about it this is because clone() is a highly specialised function to do one thing only: create a copy of the object. It therefore doesn't have much overhead to worry about - typically all it does is a field by field copy to a new object instance.
But making your objects immutable and never having to worry about cloning instances again will be faster still :-)
I've recently moved to Java, but I've had some problems with variable aliasing. I've searched everywhere, but I can't seem to find the proper way to copy the contents of one object to another object without just referencing to the same object. Does anyone have any suggestions?
Edit: What if it is an int that I am having aliasing problems with? Should I be avoiding situations like this in the first place? If so, how?
If your class implements the Clonable interface, then you can use the Object.clone() method to create a hard copy. The Wikipedia entry has some good details.
An alternative is to use copy constructors, which according to this page are safer.
It depends on the "content". For example, you cannot just copy a FileInputStream and then assume that both will continue loading from the same file.
Basically, there are two ways: If the class supports "Cloneable" interface, you can clone it by calling clone(). If not, it often has a copy constructor, that copies in data from another object.
Usually, you will end up with a shallow copy (i. e. all fields of the class are copied, but they point to the same object).
On the other hand, a lot of objects are designed to be immutable (like the String class), and there is no need to copy such an object as it cannot be changed anyway.
Another option is to design your class to create immutable objects:
http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
This avoids the need for cloning or a copy-constructor because the object cannot be changed once it is created. So multiple variables can point to the same object, but none of them can change the state of the object.
java.lang.Cloneable is what you are looking for.
You cannot have an implicit reference to a reference in Java so you cannot alias a variable.
Perhaps if you explain what you are trying to achieve, we can help do that without "aliases"
Edit: You really need to explain what you mean by aliasing an int value. An int value is anonymous at runtime so aliasing it doesn't make any sense.