I am creating a String array during the program and adding to an arraylist. After that I am calling a method getOldChildRecords with the argument as String and adding the returned String array again to the ArrayList
The String array added in line 5 is also get modified due to the method getOldChildRecords. What procedure is the best to add two different objects using line 5 and line 6.
Thanks for the reply. My requirement is that after modifying the String object, I should be able to get a second object. Presently, I am using clone() method of object class to create a new object with the same structure of the old String. I want to know whether this is a right approach or not..
I don't think that the code above compiles. I'm not sure what the answer to the question is.
Yes, Cloning is a good option.
I read in the book: "Effective Java", 1st edition, by Joshua Bloch in Item 10 that you should "Use clone() Judiciously". I can't say that I totally understand this section in "Effective Java", but it makes me wonder when I should use clone() and when I shouldn't.
Unless I'm forgetting something, Bloch's item is actually "Override clone judiciously"; here we're using the built-in clone() of an array class, which is a fine thing to do. The only alternative would be to allocate-and-copy-elements-in-a-loop to make a new array, and that's not only uglier, but less efficient.
EFH's memory is correct - Bloch says nothing against using clone methods. But if you're writing a class and want to make it Cloneable, you should override clone() and follow his advice for overriding it correctly.
I would note that there are a couple other alternatives. You can use System.arrayCopy() to copy items into an array somewhat faster than with a loop you write yourself. (It takes advantage of native code to do this.) And if you're using JDK 6 you can use Arrays.copyOf() to do this a little more elegantly, creating a new array of the appropriate type (which System.arrayCopy() does not do) and copying the contents. It should be pretty fast - almost (not quite) as fast as clone(), I think. But I think the only reason to do this rather than use clone() is if you want to change the size of the array. Since that's apparently not a requirement here, I'd say, just use clone().
He may not say it explicitly, but he is on record as saying that the cloneable interface is broken. In this interview he states:
Bill Venners: In your book you recommend using a copy constructor instead of implementing Cloneable and writing clone. Could you elaborate on that?
Josh Bloch: If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. There are a few design flaws, the biggest of which is that the Cloneable interface does not have a clone method. And that means it simply doesn't work: making something Cloneable doesn't say anything about what you can do with it. Instead, it says something about what it can do internally. It says that if by calling super.clone repeatedly it ends up calling Object's clone method, this method will return a field copy of the original.
But it doesn't say anything about what you can do with an object that implements the Cloneable interface, which means that you can't do a polymorphic clone operation. If I have an array of Cloneable, you would think that I could run down that array and clone every element to make a deep copy of the array, but I can't. You cannot cast something to Cloneable and call the clone method, because Cloneable doesn't have a public clone method and neither does Object. If you try to cast to Cloneable and call the clone method, the compiler will say you are trying to call the protected clone method on object.
The truth of the matter is that you don't provide any capability to your clients by implementing Cloneable and providing a public clone method other than the ability to copy. This is no better than what you get if you provide a copy operation with a different name and you don't implement Cloneable. That's basically what you're doing with a copy constructor. The copy constructor approach has several advantages, which I discuss in the book. One big advantage is that the copy can be made to have a different representation from the original. For example, you can copy a LinkedList into an ArrayList.
Although I agree that cloning arrays is generally a good thing. [ June 05, 2007: Message edited by: Garrett Rowe ]
Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
author and iconoclast
I'm still unclear on when I need to override the clone() method.
To allow clone() to be called on any class, that class must override clone() and make it public, as well as declare that it implements Cloneable. Why is it set up this way? It's a mystery. I suspect whoever designed it is ashamed. But you need to override it with a simple "return super.clone()" to let it be used on your class at all.
You're coming from a C++ background, I think, right? So as you can see, clone() is sort of like an inside-out copy constructor. Just as in C++, the default implementation makes a shallow copy; if you want clone() to make a deep copy, you have to override it with something more complex. Likewise if the copy should have a unique "id" member, or in short, if you want your class to be cloneable, but a straight shallow copy doesn't make sense.
Also, I want to understand how serializing and deserializing is like cloning and how it is different? (Assuming that I serialize and deserialize within the same instance of my app.).
Serialize/deserialize is an easy, but somewhat computationally expensive, way to implement a deep copy. It will make copies of every object in an arbitrary tree of objects, so it's really "deep". This is different from clone() which, as I said, makes shallow copies.
There's another difference that is exceedingly subtle; it has to do with multiple ClassLoaders. Java in General (Beginner) is not the place to discuss it. If you want to ask about this in Java in General (Advanced), I'll be happy to meet you there. Otherwise, don't worry about it for now!
Joined: Jan 30, 2000
[Garrett]: He may not say it explicitly, but he is on record as saying that the cloneable interface is broken.
Yes, and he says as much in Effective Java as well. But that's about the Cloneable interface, not the clone() method. The fact that Cloneable does not declare a clone() method is one of the things that's broken about it. But for classes that do declare a clone method, and make it public, and don't throw a CloneNotSupportedException, or make any of the other mistakes that people often make... using clone() is fine. In the case of arrays and most library classes I'm aware of, the clone() method works well. It's just the Cloneable interface that's poorly designed.
There are some subtle cases where using clone() is not recommended, in the section on making defensive copies. I don't want to get into that here as it's a special case, and beyond the scope of Java in General - Beginner. I'm just acknowldging that there are times when clone() isn't the best choice - but there's nothing inherently wrong with calling clone() on a well-designed class, if you need a copy. [ June 05, 2007: Message edited by: Jim Yingst ]
Joined: Nov 27, 2006
Thanks for the replies. I am using jdk 1.4 in my development as well as production environment and I understand from the discussion that,I can use clone for my requirement.( though I read from the replies,I haven't understood the exact difference between shallow copying and deep copying. )
Ernest Friedman-Hill: You're coming from a C++ background, I think, right?
Not exactly, I come from an Object-Oriented Pascal background. In OO Pascal, all classes must descend from TObject and two of the methods of TObject are clone() and shallowClone(). You pretty much leave shallowClone() alone because the default implementation inherited from TObject gives you a shallow copy, but if you use clone(), you have to make sure that clone() is overriden at every point in the class hierarchy where there are instance variables to be copied.
veena sasikumar I haven't understood the exact difference between shallow copying and deep copying
Someone tell me if this is different in Java, but in OO Pascal, a shallowClone() gives you a copy of an object and copies all of the primitives, pointers are copied, but what a pointer points to is not copied.
A full clone() on the other hand, not only copies all of the primitives and pointers, but also makes a copy of what each pointer points to. This includes copying all objects that are pointed to from the object that is cloned. An object that is fuly cloned is entirely independent from the original object. An object that is shallowly cloned can share some data with the original object that was cloned.