CSA Unit 1.13

Popcorn Hack #1

public class MemoryDemo {
    public static void main(String[] args) {
        // Stack variables
        int a = 10;
        int b = a;  // Copy of value
        b = 20;     // Changing b doesn't affect a
        
        System.out.println("Primitives (Stack):");
        System.out.println("a = " + a);  // Still 10
        System.out.println("b = " + b);  // Now it's 20
        
        // Heap variables
        int[] array1 = {1, 2, 3};
        int[] array2 = array1;  // Copy of reference (address)
        array2[0] = 99;         // Changing array2 DOES affect array1
        
        System.out.println("\nArrays (Heap):");
        System.out.println("array1[0] = " + array1[0]);  // Now it's 99!
        System.out.println("array2[0] = " + array2[0]);  // Also 99
    }
}
Primitives (Stack):
a = 10
b = 20

Arrays (Heap):
array1[0] = 99
array2[0] = 99

Questions

1. Why does changing b not affect a, but changing array2 affects array1

  • a and b are primitive variables stored directly on the stack.
    When b = a, a copy of the value (10) is made.
    Changing b later doesn’t affect a because they are two separate values.

  • array1 and array2 are references to the same array object in the heap.
    When array2 = array1, both point to the same memory address.
    Changing the contents of array2 also changes what array1 sees.


2. Describe what’s on the stack vs. the heap for this code

  • Stack:
    Stores local variables and references (a, b, array1, and array2).

  • Heap:
    Stores the actual array object {99, 2, 3} that both array1 and array2 reference.

Popcorn Hack #2

public class PersonDemo {
    static class Person {
        String name;
        int age;
        
        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    public static void haveBirthday(Person p) {
        p.age = p.age + 1;  // Modifying object content
        System.out.println("Inside method: " + p.name + " is now " + p.age);
    }
    
    public static void reassignPerson(Person p) {
        p = new Person("New Person", 99);  // Reassigning reference
        System.out.println("Inside reassign: " + p.name + " is " + p.age);
    }
    
    public static void main(String[] args) {
        Person john = new Person("John", 20);
        
        System.out.println("Before birthday: " + john.name + " is " + john.age);
        haveBirthday(john);
        System.out.println("After birthday: " + john.name + " is " + john.age);
        
        System.out.println("\nBefore reassign: " + john.name + " is " + john.age);
        reassignPerson(john);
        System.out.println("After reassign: " + john.name + " is " + john.age);
    }
}
Before birthday: John is 20
Inside method: John is now 21
After birthday: John is 21

Before reassign: John is 21
Inside reassign: New Person is 99
After reassign: John is 21

Questions

1. After haveBirthday(john) is called

  • John’s age: 21
  • Why:
    The haveBirthday method modifies the contents of the same Person object that both john and p reference.
    Since they point to the same memory location on the heap, increasing p.age also changes john.age.

2. After reassignPerson(john) is called

  • John’s name: “John”
  • John’s age: 21
  • Why:
    Inside reassignPerson, the parameter p is reassigned to a new Person object.
    This only changes the local reference p, not the original variable john in main().
    Therefore, john continues to refer to the original object with name “John” and age 21.

3. Modifying vs. Reassigning

  • Modifying an object’s contents:
    Changes data inside the existing object (affects all references to it).

  • Reassigning a reference:
    Changes which object a variable points to (affects only that reference, not others).

Homework Hack #1

public class ObjectCreation {
    public static void main(String[] args) {
        // 1. Create two Car objects using 'new'
        Car car1 = new Car("Tesla", 2024);
        Car car2 = new Car("Toyota", 2021);

        // 2. Print each car's info
        System.out.println("car1: " + car1);
        System.out.println("car2: " + car2);
    }
}

class Car {
    // 1. Declare variables
    String brand;
    int year;

    // 2. Create a constructor to set those variables
    public Car(String brand, int year) {
        this.brand = brand;
        this.year = year;
    }

    // 3. Add a toString() to display car info
    public String toString() {
        return "Car: " + brand + " (" + year + ")";
    }
}

Car: Tesla (2024)
Car: Toyota (2021)

Homework Hack #2

public class HeapVsStack {
    public static void main(String[] args) {
        // 1. Primitive variable
        int pages = 300;

        // 2. Copy the primitive variable
        int pagesCopy = pages;

        // 3. Create a Book object
        Book b1 = new Book("Java Basics");

        // 4. Copy the Book reference
        Book b2 = b1;

        // 5. Change original values
        pages = 500;
        b1.title = "Advanced Java";

        // 6. Print results
        System.out.println("pages: " + pages);
        System.out.println("pagesCopy: " + pagesCopy);
        System.out.println("b1: " + b1);
        System.out.println("b2: " + b2);
    }
}

class Book {
    String title;

    public Book(String title) {
        this.title = title;
    }

    public String toString() {
        return "Book title: " + title;
    }
}

pages : 500
pagesCopy : 300
b1 : Book title: Advanced Java
b2 : Book title: Advanced Java