Memra

Java objects & references (recap)

References vs values, where objects and variables live, null, and aliasing.

Variables hold references, not objects

This is the one mental model the rest of COMP 308 is built on, so re-anchor it before the advanced material.

In Java there are exactly two kinds of value:

- Primitivesbyte short int long float double boolean char. The variable *is* the value. Assigning copies the value. - Reference types — everything else (objects, arrays, String). The variable holds a reference (a handle) to an object that lives elsewhere. Assigning copies the *reference*, not the object.

The slogan from *Thinking in Java* is: "you manipulate objects with references." A reference is like a TV remote — the remote is not the TV, and several remotes can drive one TV.

Stack vs heap

Local variables and method parameters live on the stack (per call, short-lived). Objects created with new live on the heap and are reclaimed by the garbage collector once nothing references them.

int x = 10;                 // primitive: the int 10 sits on the stack
String s = new String("hi");// reference s (stack) -> String object (heap)

Aliasing: two references, one object

Because assignment copies the reference, two variables can point at the *same* object. Mutating through one is visible through the other:

StringBuilder a = new StringBuilder("cat");
StringBuilder b = a;        // b now refers to the SAME object as a
b.append("s");              // mutate through b
System.out.println(a);      // prints "cats" -- a sees the change

Contrast with primitives, where each variable is independent:

int p = 5;
int q = p;                  // q gets a COPY of the value 5
q = 99;
System.out.println(p);      // prints 5 -- p is unaffected

null and the default

A reference that points at no object holds null. Fields of reference type default to null; calling a method on a null reference throws NullPointerException at runtime.

Pass-by-value (the careful version)

Java is always pass-by-value. For a reference type the *reference* is passed by value, so the method can mutate the pointed-to object but cannot make the caller's variable point somewhere new:

static void rename(StringBuilder sb) {
    sb.append("!");          // visible to caller (same object)
    sb = new StringBuilder("x"); // reassigns the LOCAL copy only
}

After rename, the caller's builder ends in ! but is *not* the new "x" object.

Identity vs equality (preview)

a == b for references asks *"are these the same object?"* (identity). a.equals(b) asks *"are these objects logically equal?"* (value). For String, always use .equals== can lie. We return to this in the Strings and Collections modules.

NORMAL ~/memra/learn/comp-308/objects-and-references utf-8 LF