|
home—info—labs—hws—exams
textbook—java.lang docs—java.util docs—archive
Reading in book: §2.10.
Consider the following code:
int myFavoriteInt = 5; int yourFavoriteInt = 3*myFavoriteInt; (yourFavoriteInt == 15) // Will be true. myFavoriteInt = 7; // re-assigning to a variable! (More on this in week10.) (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. |
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:
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?!? |
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.
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.
Of course, sometimes you might not mean to have the same Dog referred to in two places. What is the picture which corresponds to the following?
Dog d1 = new Dog( "rover", 3 ); Dog d2 = new Dog( "rex", 5 ); Dog d3 = new Dog( "fifi", 7 ); // Draw the picture of what things look like right here. Kennel k1 = new Kennel( "123 puppy lane", d1, d2 ); // Draw the picture of what things look like right here. Kennel k2 = new Kennel( "456 puppy lane", d1, d3 ); // Draw the picture of what things look like right here. |
// continuing from above... Kennel k3 = new Kennel( "789 puppy lane", d1, new Dog( "rex", 5 ) ); Kennel k4 = new Kennel( "000 puppy lane", d1, d1 ); |
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.
This next bit isn't something you'll be tested on, but it might help some people understand the notion of passing references.
The pictures we've been drawing (including the box for local variables and parameters, as well as the big red boxes for objects) are stored in the computer's main memory. Main memory, internally, is an “array”: a big row of boxes, each labeled with a numeric address (between 0 and a billion, if you have 1Gig of memory). The Dog object with name "fifi" and age 7 might happen to get stored at memory address @300000. If that's the case, then the variable myFavoriteDog contains the value “@300000” — that's the arrow we've been drawing! (Technically: it is the computer's internal representation of the arrow.)
Therefore: when you pass myFavoriteDog to a method: the value @300000 is written down on a piece of paper, and given to that method.
To do: Can you explain the result of calling myFavoriteDog.toString()? We didn't write this function ourselves, but “toString” is such a useful function that Java wrote it for us. However, it doesn't know how a string-representing-a-Dog should look like, so it does something a bit silly.
Note that
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 Some languages, like C++, do let you have references to local variables. Today's accepted wisdom is that this language feature may let you do a couple of things more conveniently (like swap local variables), but overall it leads to much more confusion than it's worth. ↩
home—info—labs—hws—exams
textbook—java.lang docs—java.util docs—archive
©2008, Ian Barland, Radford University Last modified 2008.Aug.31 (Sun) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |