Conditional Expressions and Statements : 08/24/2023
Operations on Variables : 08/23/2023
Variables and Types : 08/22/2023
Welcome to CS 124 : 08/21/2023
References
publicclassPerson {
privateStringname;
publicPerson(StringsetName) {
name=setName;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(StringsetName) {
name=setName;
}
}
Personme=newPerson("Geoff");
Personyou=me;
you.setName("Fantastic Student");
System.out.println(me.getName());
Here we begin a series of lessons that will deepen our understanding of Java.
They will also introduce an incredibly important and prevalent idea in computer science—references.
So let’s get started!
As we frequently do, we’ll begin with a puzzle.
Examine the following code (duplicated from the lesson header) and try to predict what should happen:
publicclassPerson {
privateStringname;
publicPerson(StringsetName) {
name=setName;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(StringsetName) {
name=setName;
}
}
Personme=newPerson("Geoff");
Personyou=me;
you.setName("Fantastic Student");
System.out.println(me.getName());
The critical bit is the line Person you = me.
There are two things that could happen here:
Java could make a copy of me and save it to you, meaning that at that point there would be twoPerson objects; or
Something else…
Given the result, the answer is clearly the latter.
On some level we should find this reassuring, since previously we had said that (1) objects are only created when you see new and (2) Java does not have a built in way of making object copies.
However, it does leave us with the question: what is happening, and why?
Until this lesson we’ve been somewhat vague about exactly what is being stored in our variables.
No longer.
Variables in Java that store objects do not store the object instance itself.
Rather, they store a reference to the instance.
What is a reference?
I’m glad you asked!
Wikipedia says.
In computer science, a reference is a value that enables a program to indirectly access a particular datum, such as a variable’s value or a record, in the computer’s memory or in some other storage device. The reference is said to refer to the datum, and accessing the datum is called dereferencing the reference.
In Java, when we assign an instance of an object to a variable, what we are really doing is creating a reference variable.
The variable stores a reference to the object, not the object itself:
Strings=newString("count"); // s stores a reference to a String with value "count"
Stringt=s; // t now also stores a reference to the _same_ String
System.out.println(t.length());
If and when you get lost here, here’s something that will help.
Objects are only created when you see new.
In the example above, even though we have two reference variables (s and t), we have only oneString created using new.
A reference is not the thing it refers to.
This becomes clear when we examine some real-world examples of references:
A phone number is a reference. It is not the phone that rings.
An address is a reference. It is not whatever is located there.
Your university ID number is a reference. It is not you!
In each of these cases above, a reference is something that we can use to access the object it refers to.
If I give you my phone number, you can call me.
If I give you my address, you can visit!
If I make a bunch of copies of my address, you could all come over and visit!
But I would still only have one house.
Changes to Objects Are Visible to Reference Holders
Let’s continue the analogy above.
Imagine I give two of you the address to my house.
The next day, one of you comes by and “decorates” my house with sanitary paper.
If the other comes by later, they also see the change!
publicclassHouse {
publicbooleanhasTP=false;
}
Housefirst=newHouse();
Housesecond=first;
System.out.println(first.hasTP);
second.hasTP=true; // Please don't actually do this!
System.out.println(first.hasTP);
So the next rule of references: changes to object instances are visible to all reference holders.
This is why, in the example above, me.getName() returns “Fantastic Student” even though the change was made using the reference variable you.
Both refer to the same object, the only one that was created using new.
Note that all that we said above is not true for Java primitive types.
They store their values directly in the variable:
inti=8;
intj=i; // The value from i is copied into j
j++;
System.out.println(j);
System.out.println(i);
But this only works for the eight primitive types.
Any variable that stores an object in Java is a reference variable, and actually stores an object reference.
Finally, this also gives us a better understanding of null.
null is the empty reference:
Strings=null;
null indicates that a variable that could store a reference does not, and is empty.
This also explains what happens if we try and follow or deference null.
(Imagine if I told you to call a phone number, but then handed you a blank sheet of paper!)
Imagine I have the following code, and I want to swap the objects that me and you refer to.
(Searching for the fountain of youth, I guess…)
Let’s walk through how we would do that:
publicclassPerson {
privateintage;
Person(intsetAge) {
age=setAge;
}
publicintgetAge() {
returnage;
}
}
Personme=newPerson(41);
Personyou=newPerson(18);
Next, let’s examine a similar example using a diagram:
To wrap up, we are now ready to understand the difference between == and .equals when comparing objects.
== tests reference equality, while .equals tests instance equality.
Let’s examine the difference:
publicclassExample {
privateintvalue;
publicExample(intsetValue) {
value=setValue;
}
publicbooleanequals(Objecto) {
if (!(oinstanceofExample)) {
returnfalse;
}
Exampleother= (Example) o;
returnvalue==other.value; // == because we are comparing primitive types
}
}
Examplefirst=newExample(88);
Examplesecond=newExample(88);
Examplethird=first;
System.out.println(first==second);
System.out.println(first.equals(second));
System.out.println(first==third);
System.out.println(first.equals(third));
Practice: Object v. Reference Equality
Created By: CS 124 Staff
/ Version: 2020.10.0
Implement a public class method named compare on a public class Comparison that accepts two Object arguments.
It should return 0 if both references are equal, 1 if both objects are equal, and -1 otherwise.
Either reference can be null, so you'll need to handle those cases carefully!
This problem deadline has passed, but you can continue to practice. Experiment! You will not lose credit.
Homework Restricted to Current CS 124 Students
A publicly-accessible version of this content is available at learncs.online.
Practice: Mystery Method 1
Created By: CS 124 Staff
/ Version: 2020.10.0
This homework problem is a bit different.
There is no description!
Instead, you should use our testing suite and its error messages to help you figure out what to do!
This is also known as reverse engineering.
Good luck, and have fun!
This problem deadline has passed, but you can continue to practice. Experiment! You will not lose credit.
Homework Restricted to Current CS 124 Students
A publicly-accessible version of this content is available at learncs.online.
Homework: Mystery Method 2
Created By: CS 124 Staff
/ Version: 2021.9.0
This homework problem is a wee bit different.
There is no description!
Instead, you should use our testing suite and its error messages to help you figure out what to do!
This is also known as reverse engineering.
Good luck, and have fun!
This problem deadline has passed, but you can continue to practice. Experiment! You will not lose credit.
Homework Restricted to Current CS 124 Students
A publicly-accessible version of this content is available at learncs.online.