Object Creation and Storage (Instantiation)
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
}
}
MemoryDemo.main(null);
Primitives (Stack):
a = 10
b = 20
Arrays (Heap):
array1[0] = 99
array2[0] = 99
Changing b doesn’t affect a because int is a primitive type, and primitives store their actual values on the stack. When you assign b = a, a copy of a’s value (10) is made—so later changing b doesn’t change a.
On the other hand, array1 and array2 are references to an object (the array) stored on the heap. When you assign array2 = array1, both variables point to the same memory location in the heap. Changing one changes the shared array, so both see the update.
Stack: holds variables a, b, and references (addresses) to array1 and array2. Heap: holds the actual array object {99, 2, 3}.
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);
}
}
PersonDemo.main(null);
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
After haveBirthday(john) is called, John’s age becomes 21. This is because the method modifies the contents of the same Person object in memory. The reference p inside the method points to the same object as john, so updating p.age directly changes John’s age.
After reassignPerson(john) is called, John’s name and age remain “John” and 21. In this case, the method creates a new Person object and reassigns the local variable p to it, but this does not change what john points to outside the method.
Difference:
Modifying an object’s contents (like p.age = 21) changes the actual object on the heap that both references share.
Reassigning a reference (like p = new Person(…)) only changes the local reference variable—it does not affect the original variable outside the method.
Homework Hack 1
// Homework Hack #1: Object Creation Practice
public class ObjectCreation {
public static void main(String[] args) {
// 1. Create two Car objects using 'new'
// Example: Car car1 = new Car("Tesla", 2024);
Car car1 = new Car("Tesla", 2024);
Car car2 = new Car("Ford", 2020);
// 2. Print each car's info
// Example: System.out.println(car1);
System.out.println(car1);
System.out.println(car2);
}
}
class Car {
// 1. Declare variables: brand, year
String brand;
int year;
// 2. Create a constructor to set those variables
Car(String brand, int year) {
this.brand = brand;
this.year = year;
}
// 3. Add a method or toString() to display car info
public String toString() {
return brand + " (" + year + ")";
}
}
ObjectCreation.main(null);
Tesla (2024)
Ford (2020)
Popcorn Hack #2
// Homework Hack #2: Heap vs Stack Storage Demo
public class HeapVsStack {
public static void main(String[] args) {
// 1. Create a primitive variable (int pages)
int pages = 100;
// 2. Create another primitive variable that copies it
int pagesCopy = pages;
// 3. Create a Book object (Book b1 = new Book("Java Basics");)
Book b1 = new Book("Java Basics");
// 4. Create another Book reference (Book b2 = b1;)
Book b2 = b1;
// 5. Change the original primitive and the Book title
pages = 200;
b1.title = "Advanced Java";
// 6. Print both sets of values to compare behavior
System.out.println("pages = " + pages);
System.out.println("pagesCopy = " + pagesCopy);
System.out.println("b1 = " + b1);
System.out.println("b2 = " + b2);
}
}
class Book {
// 1. Declare variable: String title
String title;
// 2. Create a constructor to set the title
Book(String title) {
this.title = title;
}
// 3. Create a toString() to show the title
public String toString() {
return title;
}
}
HeapVsStack.main(null);
pages = 200
pagesCopy = 100
b1 = Advanced Java
b2 = Advanced Java