RU beehive logo ITEC dept promo banner
ITEC 120
2008spring
ibarland,
jdymacek

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lect08b
references as values, cont
swapping locals vs swapping fields

Swapping Fields

Todo: Write the following method, inside class Dog1 Assume you have getters and setters for all fields.

/** Exchange the sounds of this dog and another dog.
 * @param other The Dog to exchange sounds with.
 */
void swapSoundsWith( Dog other ) {

  }
 
(lect08b-soln.html)

I can call this from method from the bench:

Dog myDog     = new Dog( "rex",      5 );
myDog.setSound( "Rrrrrrr!" );
Dog movieStar = new Dog( "Air Bud", 17 );

myDog.getSound()      // Returns                 
myDog.getAge()        // Returns                 
movieStar.getSound()  // Returns                  (the default sound)
movieStar.getAge()    // Returns                 

myDog.swapSoundsWith(movieStar)

myDog.getSound()      // Returns                 
myDog.getAge()        // Returns                 
movieStar.getSound()  // Returns                  (the default sound)
movieStar.getAge()    // Returns                 
Question: Does our local variable myDog still refer to the same dog it did at the start?

You can't write a function to swap your own local variables

  void tryAndSwap( int a, int b ) {
    int tmp;
    tmp = a;
    a = b;     // Assigning to a parameter -- bad style!
    b = tmp;   // Assigning to a parameter -- bad style!
    }
What happens when we try this?
int myFavoriteInt = 5;
int yourFavoriteInt = 23;

tryAndSwap( myFavoriteInt, yourFavoriteInt );

myFavoriteInt == 5     // True, or false?
yourFavoriteInt == 5   // True, or false?
If you draw the pictures of what happens, you'll see that tryAndSwap made its own local variables (a and b), they were initialized when the function was called (with 5 and 23), those local variables were shuffled around, but myFavoriteInt was never touched!

We say: “Java always passes arguments by value”: it takes the actual argument's value, and uses (a copy of) that value to initalize the parameter. The thing to realize is that (in java) “references are values”.

Some languages allow something different: they let you “pass arguments by reference”, a special language-feature that would let you write something like swapInts(int,int). However, this has fallen out of favor recently, and is commonly viewed as something which can add obscure bugs without really giving the programmer more power. Just write methods which return a (reference to) the new items, and assign your variables explicitly.

Further reflections

Some more ramifications of local variables, and

int x = 16.0;
Math.sqrt(x)
x
It's no surprise that x still has the value 16.0, even though we happened to give That is because we wrote down 16.0 on a piece of paper and gave the paper to Math.sqrt; (If you thought Math.sqrt(x) should change the value of x, what should it do when given Math.sqrt(x+3) or Math.sqrt(x+2*y)?)

Note that while the argument itself cannot be changed, the fields of that argument can be. Assigning to the parameters doesn't actually modify what value was passed in:

  void addSevenTo( int n ) { n = n+7; }  // An utterly useless method.
  
  int addSevenTo_v2( int n ) { 
    n = n+7;  // Still bad practice, assigning to a parameter.
    return n; // But does give the correct answer.
    }

  int addSevenTo_v3( int n ) { return n+7; }    // Acceptable style.
  
  
  int zz = 5;
  addSevenTo(zz);    // zz is still 5.
  addSevenTo(zz+3);  // zz+3 is still 8.
  addSevenTo(19);    // 19 is still 19.
  
  addSevenTo_v2(zz)     // returns 12; zz is still 5.
  addSevenTo_v2(zz+3)   // returns 15; zz+3 is still 8.
  addSevenTo_v2(19)     // returns 26; 19 is still 19.
  
Similarly, it is impossible to write a function void swapInts(int,int), or void swapDog(Dog,Dog)!. (The closest we could get in the second case is a method void swapDogSoundAndAge(Dog,Dog).)
  Dog d1 = new Dog();
  Dog d2 = new Dog();
  d1.ageOneYear();
  Dog bestDog = d1;
  d1.setSound( "meow?" );
  d1.swapSoundsWith(d2);  // Whatever this method does, ...
  (d1 == bestDog)   // ... this line MUST be true, even if d1's sound and age have both changed.
  


1 Although perhaps, maybe it should better be a method of MadScientist, with void swapDogsSounds( Dog a, Dog b ).      

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2008, Ian Barland, Radford University
Last modified 2008.Mar.07 (Fri)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme