Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > when using Class type as method parameters, I have a question...

Reply
Thread Tools

when using Class type as method parameters, I have a question...

 
 
www
Guest
Posts: n/a
 
      11-07-2007
Hi,

I thought I have understood this issue without any problems already.
When using class type parameters for a method, the behavior is kind of
like pass-by-reference. The object can be modified by the code inside
the method, right? But today, I ran into an interesting problem: the
object cannot get the change it wants.

Suppose I have a class called Species. I have a method

//oldSpecies is an object of Species, its content has been set already.
//newSpecies is an object of Species, but its content has not been set
yet. i.e. its content all has been set by the default values. The
purpose of this method is to set newSpecies content based on different
condition.
public static void convertOldSpeciesToNewSpecies(Species oldSpecies,
Species newSpecies)
{
if(..) //BLOCK A
{
newSpecies = oldOne; //just assign it. Here is the problem! The
caller, the second parameter, does not get the value
}
else //BLOCK B
{
//in this case, newSpecies get assigned values. No problem, the caller
gets the value.
newSpecies.setXXX
newSpecies.setYYY

}

//print out newSpecies content
System.out.println(newSpecies.toString());
}


Helper.convertOldSpeciesToNewSpecies(speciesOne, speciesTwo);

Above calling, if the condition fits BLOCK B, result is correct
(speciesTwo gets the values it should get from inside the method).

But if the condition fits BLOCK A, speciesTwo does NOT get the content
of speciesOne. The printing inside the method shows that newSpecies has
got the correct content (same as speciesOne).

What is the problem? Thank you very much.

For my practical reason, I do not want to change the method to

public Species getNewSpecies(Species oldSpecies){..}
 
Reply With Quote
 
 
 
 
lyallex
Guest
Posts: n/a
 
      11-07-2007
www wrote:
> Hi,
>
> I thought I have understood this issue without any problems already.
> When using class type parameters for a method, the behavior is kind of
> like pass-by-reference. The object can be modified by the code inside
> the method, right? But today, I ran into an interesting problem: the
> object cannot get the change it wants.
>
> Suppose I have a class called Species. I have a method
>
> //oldSpecies is an object of Species, its content has been set already.
> //newSpecies is an object of Species, but its content has not been set
> yet. i.e. its content all has been set by the default values. The
> purpose of this method is to set newSpecies content based on different
> condition.
> public static void convertOldSpeciesToNewSpecies(Species oldSpecies,
> Species newSpecies)
> {
> if(..) //BLOCK A
> {
> newSpecies = oldOne; //just assign it. Here is the problem! The
> caller, the second parameter, does not get the value
> }
> else //BLOCK B
> {
> //in this case, newSpecies get assigned values. No problem, the
> caller gets the value.
> newSpecies.setXXX
> newSpecies.setYYY
>
> }
>
> //print out newSpecies content
> System.out.println(newSpecies.toString());
> }
>
>
> Helper.convertOldSpeciesToNewSpecies(speciesOne, speciesTwo);
>
> Above calling, if the condition fits BLOCK B, result is correct
> (speciesTwo gets the values it should get from inside the method).
>
> But if the condition fits BLOCK A, speciesTwo does NOT get the content
> of speciesOne. The printing inside the method shows that newSpecies has
> got the correct content (same as speciesOne).
>
> What is the problem? Thank you very much.
>
> For my practical reason, I do not want to change the method to
>
> public Species getNewSpecies(Species oldSpecies){..}


I think I see what you are asking although your example is not very
clear, you are using multiple names (newSpecies, oldSpecies, speciesOne,
speciesTwo, oldOne and what have you) which confuses things a bit.

Arguments to methods are passed call by value in Java, it just so
happens that when you pass a reference in, the value is a memory
address. In the method body, copies of the values are used so you will
have a copy of (say) the memory address of newSpecies and a copy of the
memory address of oldSpecies.

Now to begin with, these copies still point to the original Objects so
you can modify those objects directly by calling their methods, however
if you assign one reference to another all you are doing is modifying
the copies not the values (memory addresses) of the arguments.

Write some more code to assign a value to a modified local copy and see
if you can figure out what's going on, stick with it, you will get there
in the end.


 
Reply With Quote
 
 
 
 
www
Guest
Posts: n/a
 
      11-07-2007
lyallex wrote:


> Arguments to methods are passed call by value in Java, it just so
> happens that when you pass a reference in, the value is a memory
> address. In the method body, copies of the values are used so you will
> have a copy of (say) the memory address of newSpecies and a copy of the
> memory address of oldSpecies.
>
> Now to begin with, these copies still point to the original Objects so
> you can modify those objects directly by calling their methods, however
> if you assign one reference to another all you are doing is modifying
> the copies not the values (memory addresses) of the arguments.
>


Thank you for your help. Now I understand it:

public static void convertOldSpeciesToNewSpecies(Species oldSpecies,
Species newSpecies){..}

Helper.convertOldSpeciesToNewSpecies(speciesOne, speciesTwo);

Now, oldSpecies has the memory address of the object speciesOne,
newSpecies has the memory address of the object speciesTwo.

If condition is such so that goes to BLOCK A, newSpecies has the memory
address of the object speciesOne, due to the code BLOCK A. *BUT*, the
object speciesTwo remain un-modified. That is why speciesTwo didn't get
what it should get after the method calling.




 
Reply With Quote
 
lyallex
Guest
Posts: n/a
 
      11-07-2007
www wrote:
> lyallex wrote:
>
>
>> Arguments to methods are passed call by value in Java, it just so
>> happens that when you pass a reference in, the value is a memory
>> address. In the method body, copies of the values are used so you will
>> have a copy of (say) the memory address of newSpecies and a copy of
>> the memory address of oldSpecies.
>>
>> Now to begin with, these copies still point to the original Objects so
>> you can modify those objects directly by calling their methods,
>> however if you assign one reference to another all you are doing is
>> modifying the copies not the values (memory addresses) of the arguments.
>>

>
> Thank you for your help. Now I understand it:
>
> public static void convertOldSpeciesToNewSpecies(Species oldSpecies,
> Species newSpecies){..}
>
> Helper.convertOldSpeciesToNewSpecies(speciesOne, speciesTwo);
>
> Now, oldSpecies has the memory address of the object speciesOne,
> newSpecies has the memory address of the object speciesTwo.
>
> If condition is such so that goes to BLOCK A, newSpecies has the memory
> address of the object speciesOne, due to the code BLOCK A. *BUT*, the
> object speciesTwo remain un-modified. That is why speciesTwo didn't get
> what it should get after the method calling.
>


It takes a while doesn't it, but I reckon you are getting there.
Keep at it, it's all worth it in the end
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      11-07-2007
On Wed, 07 Nov 2007 12:46:03 -0500, www <(E-Mail Removed)> wrote, quoted
or indirectly quoted someone who said :

> newSpecies = oldOne; //just assign it. Here is the problem! The
>caller, the second parameter, does not get the value


That will not work. That just makes newSpecies point to the same
object that oldOne does. Any changes you make to the fields of
newSpecies will modify the fields in oldOne.

You need do something like this;

newSpecies = oldOne.clone();

See http://mindprod.com/jgloss/clone.html

or

newSpecies = new Species (oldOne);
// a copy constructor

or

newSpecies = new Species();
newSpecies.legCount = oldOne.legCount;
...

Also be aware that if you make the parameter local variable point to a
new object, it will have NO effect on the caller. You have either
modify the object passed or return a reference to a new object.

I think you would do well to invest some time reading a introductory
Java textbook that explains these mysteries. Even a badly out of date
second hand one (and hence very cheap) would do.

--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      11-07-2007
www wrote:
> Hi,
>
> I thought I have understood this issue without any problems already.
> When using class type parameters for a method, the behavior is kind of
> like pass-by-reference. The object can be modified by the code inside
> the method, right? But today, I ran into an interesting problem: the
> object cannot get the change it wants.
>
> Suppose I have a class called Species. I have a method
>
> //oldSpecies is an object of Species, its content has been set already.
> //newSpecies is an object of Species, but its content has not been set
> yet. i.e. its content all has been set by the default values. The
> purpose of this method is to set newSpecies content based on different
> condition.
> public static void convertOldSpeciesToNewSpecies(Species oldSpecies,
> Species newSpecies)
> {
> if(..) //BLOCK A
> {
> newSpecies = oldOne; //just assign it. Here is the problem! The
> caller, the second parameter, does not get the value
> }
> else //BLOCK B
> {
> //in this case, newSpecies get assigned values. No problem, the
> caller gets the value.
> newSpecies.setXXX
> newSpecies.setYYY
>
> }
>
> //print out newSpecies content
> System.out.println(newSpecies.toString());
> }
>
>
> Helper.convertOldSpeciesToNewSpecies(speciesOne, speciesTwo);
>
> Above calling, if the condition fits BLOCK B, result is correct
> (speciesTwo gets the values it should get from inside the method).
>
> But if the condition fits BLOCK A, speciesTwo does NOT get the content
> of speciesOne. The printing inside the method shows that newSpecies has
> got the correct content (same as speciesOne).
>
> What is the problem? Thank you very much.
>
> For my practical reason, I do not want to change the method to
>
> public Species getNewSpecies(Species oldSpecies){..}


The reference itself is passed by value. newSpecies is a reference
holder, not an actual reference.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
why a class can't access protected method from another class in thesame package,the method is interited from the ohtner class from differntpackage? junzhang1983@gmail.com Java 3 01-28-2008 02:09 AM
how to call method of the class which contains a pointer to other class method? Pawel_Iks C++ 3 07-31-2007 06:30 AM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Re: How do I access another type's method from one type's method Howard C++ 2 07-04-2003 12:08 PM
Re: How do I access another type's method from one type's method Rolf Magnus C++ 1 07-04-2003 02:38 AM



Advertisments