RU beehive logo ITEC Department logo
ITEC 120
2007spring
ibarland,
jpittges

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lect09a
References as Values
lect09a

Consider the following code:

int myFavoriteInt   = 5;
int yourFavoriteInt = 3*myFavoriteInt;

(yourFavoriteInt == 15)  // Will be true.

myFavoriteInt = 7;    // re-assigning to a variable!

(yourFavoriteInt == 15)  // Will be true.

Math.Sqrt(yourFavoriteInt);  // Doesn't change the value of yourFavoriteInt.
/* ...more code which never assigns to "yourFavoriteInt"... */

(yourFavoriteInt == 15)  // Will be true.
You can't change the value of yourFavoriteInt without having it be on the left hand side of the assignment statement. 1

We have already seen the assignment statement in the context of initializing a local variable:
assignment-statement ::= name = expression;
The semantics of the assignment statement are straightforward:

  1. Evaluate the right-hand-side expression,
  2. store that value into the location labeled by name.

But compare with:

Dog myFavoriteDog   = new Dog();
Dog yourFavoriteDog = myFavoriteDog;

/* ...code which never *assigns* to "yourFavoriteDog", 
      and moreover, never even *mentions* it. */

(myFavoriteDog == yourFavoriteDog)    // Will be true.
(yourFavoriteDog.getAge() == 0)       // Might be false?!?

(Pictures on board)

But that doesn't mean that variables-holding-object-references (my,yourFavoriteDog) work differently than variables-holding-primitive-values (my,yourFavoriteInt). In fact, the variables work exactly the same: The value of myFavoriteDog never changed -- it is still a reference to the same dog. Agreed, the state of the Dog has been modified over time, but it's still the same Dog!.

So: you can't change the value of a variable without assigning to it, whether it's a primitive type or an object reference. 2 But, the contents of an object might change, even if your variable which references the object isn't explicitly mentioned in the code.

Multiple References can be intended

Is it a mistake, to allow myFavoriteDog and yourFavoriteDog to be two different ways of referring to the exact same Dog? Well, what happens if your favorite dog starts meowing? Well then, so does my favorite dog! So it's appropriate that changing the dog's sound is independent of how you and I each refer to that same dog.

Similarly, in the program for the registrar's office, there might be only one Student object corresponding to you, but several different variables which all refer to you. Your Dorm has a list of students which will include a reference to you; the Registrar has a list of all-students, as well as a list of honor-students and a list of students-with-outstanding-fines; you might be on all of these lists, or perhaps only one!

I had to apply for a university library card, and they had me fill out yet-another-form, with my phone number etc.. It turns out, that the library-program doesn't use the objects made by the Registrar's computer; I had to fill out a separate card (and re-list my name, phone-number, etc.). If I ever change my phone number, I'll need to tell both the library and the registrar to change it. This is poor data representation; there should be a single instance of (the object representing) me which all the different functions access.

On the other hand, for social reasons, perhaps it's good not to have a single central object with all the information:

The drawback of a lack of centralized database is that a criminal might be wanted by the police, yet still able to apply for parking permits and credit cards because there is no central database. (Or even, I might be wanted by the FBI, and yet when I'm pulled over by a local sherrif for speeding, the FBI information may not be shared with other systems, and I go free.) The costs and benefits of implementing the data the “correct” way (from a programmer's point of view) must be weighed with social realities.

Assigning to Parameters; Swapping fields

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 parameter itself cannot be changed, the fields of that parameter 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.
  
Todo: Write the following method, inside class Dog3 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 ) {

  }
 

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.


1By the way, notice that Java variables work differently than spreadsheet cells: in a spreadsheet, if Y1 = 3 * M1, then any changes to M1 do cause Y1 to change. Java variables are not so sophisticated. But there are some programming languages for the web which do use such “reactive” variables.      

2Really, the truth is that assignment to the field of an object, (like this.age = 3) is very different than assignment to a variable (like n = 3). In fact, some languages refuse to use = for both of these situations: in Lisp, for example, set! is used to assign to variables, and set-Dog-age! is used to assign to the age field of a Dog.      

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

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2007, Ian Barland, Radford University
Last modified 2007.Aug.27 (Mon)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme