wood burning stoves 2.0*
The moose likes Beginning Java and the fly likes pass by reference problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Beginning Java
Bookmark "pass by reference problem" Watch "pass by reference problem" New topic
Author

pass by reference problem

veena sasikumar
Greenhorn

Joined: Nov 27, 2006
Posts: 29
Hi all,

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 in adavance

veena
Kaydell Leavitt
Ranch Hand

Joined: Nov 18, 2006
Posts: 689

Remember that all arrays are objects. Remember the difference between copying an object and merely copying an object's reference variable.

Kaydell
[ June 04, 2007: Message edited by: Kaydell Leavitt ]
veena sasikumar
Greenhorn

Joined: Nov 27, 2006
Posts: 29
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..

Thanks in advance

Veena
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3344

Yes, Cloning is a good option.


Everything has got its own deadline including one's EGO!
[CodeBarn] [Java Concepts-easily] [Corey's articles] [SCJP-SUN] [Servlet Examples] [Java Beginners FAQ] [Sun-Java Tutorials] [Java Coding Guidelines]
Kaydell Leavitt
Ranch Hand

Joined: Nov 18, 2006
Posts: 689



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.

Kaydell
[ June 05, 2007: Message edited by: Kaydell Leavitt ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

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.


[Jess in Action][AskingGoodQuestions]
Kaydell Leavitt
Ranch Hand

Joined: Nov 18, 2006
Posts: 689


Unless I'm forgetting something, Bloch's item is actually "Override clone judiciously"


Thanks Dr. Hill.

I'm still unclear on when I need to override the clone() method.

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.).

Kaydell
[ June 05, 2007: Message edited by: Kaydell Leavitt ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
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().


"I'm not back." - Bill Harding, Twister
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Bloch says nothing against using clone methods.

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
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by Kaydell Leavitt:

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!
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[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 ]
veena sasikumar
Greenhorn

Joined: Nov 27, 2006
Posts: 29
Hi all,

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. )

regards
veena
Kaydell Leavitt
Ranch Hand

Joined: Nov 18, 2006
Posts: 689


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.

Kaydell
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: pass by reference problem