Popcorn Hacks
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 they’re primitive types stored by value on the stack — b gets its own copy. array1 and array2 are references to the same array in the heap, so changing one affects the other.
Stack: holds primitive variables (a, b) and references to objects (array1, array2). Heap: holds the actual array object {99, 2, 3} that both references point to.
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 is 21, because the method modifies the contents of the same Person object in the heap that john references.
After reassignPerson(john) is called, John’s name and age remain “John, 21”, because the method only reassigns the local reference p to a new object, without changing the original john reference in main.
Difference:
Modifying an object’s contents changes the data stored in the same heap object, visible to all references pointing to it.
Reassigning a reference only changes the local variable to point somewhere else; it doesn’t affect other references to the original object.
Homework Hacks
Popcorn 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("Ford", 2020);
// 2. Print each car's info
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
@Override
public String toString() {
return "Brand: " + brand + ", Year: " + year;
}
}
ObjectCreation.main(null);
Brand: Tesla, Year: 2024
Brand: Ford, Year: 2020
// 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 = 300;
// 2. Create another primitive variable that copies it
int pagesCopy = pages;
// 3. Create a Book object
Book b1 = new Book("Java Basics");
// 4. Create another Book reference
Book b2 = b1;
// 5. Change the original primitive and the Book title
pages = 500;
b1.title = "Advanced Java";
// 6. Print both sets of values to compare behavior
System.out.println("Primitive variables:");
System.out.println("pages = " + pages); // 500
System.out.println("pagesCopy = " + pagesCopy); // 300
System.out.println("\nBook objects:");
System.out.println("b1 = " + b1); // Advanced Java
System.out.println("b2 = " + b2); // Advanced Java
}
}
class Book {
// 1. Declare variable: String title
String title;
// 2. Constructor to set the title
Book(String title) {
this.title = title;
}
// 3. toString() to show the title
@Override
public String toString() {
return "Book title: " + title;
}
}
HeapVsStack.main(null);
Primitive variables:
pages = 500
pagesCopy = 300
Book objects:
b1 = Book title: Advanced Java
b2 = Book title: Advanced Java