References: Arrows, ==, and Aliasing
Where you are: Week 0 review > References, ==, and aliasing
Try This First
Predict the last line before reading on:
Book b1 = new Book("Java", 30.00);
Book b3 = b1;
b3.setPrice(10.00);
System.out.println(b1.getPrice());
Reveal
10.0. The line Book b3 = b1; copies the arrow, not the object, so b1 and b3 point at the same Book. A change through one is visible through the other.
Before You Start
Check each box you can do from memory. A box you cannot check yet is not a problem; it points you to a quick refresher, not a grade.
See Writing a Class: Fields, Constructors, and Encapsulation if any box above feels uncertain.
Not sure? Take the 60-second self-check.
Try each from memory, then read the answer under it.
- What does a class group together? Fields (the data) and methods (the behavior) for one kind of thing.
- What does an object created from a class hold? Its own copy of the fields, set up by the constructor.
What You Need To Walk In With
Walk into the next class able to state these:
- A variable of a class type does not contain the object. It contains an arrow (a reference) to the object on the heap. A primitive variable, by contrast, contains its value directly.
- Assigning one reference to another copies the arrow. Both names then point at the same object; they are aliases, and a change through one shows through the other.
==compares the arrows (identity): are these the same object? Without anequalsoverride,.equals()also compares arrows.- Two separately built objects with identical fields are not
==, because they are different objects.
You should be able to: predict aliasing after assignment, and state what == compares for objects.
How It Works
For a primitive, the variable is a box holding the value: int x = 7 puts 7 in x. For an object, the variable holds an address, an arrow to where the object lives:
b1 ---------> Book{ title=Java, price=30.00 }
b3 ---------/ (same object after b3 = b1)
Copying a reference copies the arrow, not the object:
Book b1 = new Book("Java", 30.00);
Book b3 = b1; // copy the arrow; b1 and b3 are aliases
b3.setPrice(10.00);
System.out.println(b1.getPrice()); // 10.0
== on objects asks “same arrow?” Two separate allocations are different objects, so == is false even when every field matches:
Book a = new Book("Java", 30.00);
Book b = new Book("Java", 30.00);
System.out.println(a == b); // false: different objects
Without an equals override, a.equals(b) is also false, because the inherited equals is just ==. Comparing contents needs an equals override.
Worked Example: Predict, Then Check
Book a = new Book("Java", 30.00);
Book b = new Book("Java", 30.00);
Book c = a;
System.out.println(a == b);
System.out.println(a == c);
Predict both lines before reading on.
Reveal
false then true. a and b are separate objects, so a == b is false. c = a copies the arrow, so a and c are the same object and a == c is true.
A Common Mistake
A frequent belief is that == compares the contents of two objects. For object types, == compares arrows (identity), not fields. Two Book objects with the same title and price are not ==. To compare contents, override equals and call .equals() (covered in equals and hashCode). For text, use s1.equals(s2), not s1 == s2. (Source: BJP (Reges and Stepp), Ch 8; JLS 25, §15.21.3.)
Go Deeper (optional)
For the curious: a null reference is an arrow that points at nothing. Calling a method through it (b.getPrice() when b is null) throws a NullPointerException, because there is no object at the end of the arrow. Checking if (b != null) before use, or designing so a reference is never null, prevents it.
Check Yourself
Close the notes and answer each one from memory, then reveal it. Pulling an idea back from memory is one of the strongest ways to make it stick.
Check your understanding
Book b3 = b1; b3.setPrice(10.00); print(b1.getPrice()). What prints?
For two object references, what does == compare?
a and b are two new Book objects with identical fields. What is a == b ?
A Book has no equals override. What does a.equals(b) compare?