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
-
b does not affect a but array2 affects array1 because primitive types aren’t stored directly in the stack. So when you assign b to a, b copies a into a new location in the memory. This is not the same for arrays because they both point to the same array in the memory.
-
The stack holds method call frames and local variables, which are a, b, array1 and array2. A heap stores the actual objects in the array.
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 it’s called, John’s age is now 21 because haveBirthday will modify the contents of the same Person object that John refers to. Changing p.age updates the same memory location since both p and john point to the same object in the heap.
-
After it’s called, the name and age do not change. Inside the method, p is reassigned to a new Person. This changes what the local copy points to.
-
Modifying contents changes the data stored inside the object that both references share. Reassigning a reference changes what the reference points to.
Homework Hack 1
public class ObjectCreation {
public static void main(String[] args) {
Car car1 = new Car("Tesla", 2024);
Car car2 = new Car("Toyota", 2020);
System.out.println(car1);
System.out.println(car2);
}
}
class Car {
String brand;
int year;
Car(String brand, int year) {
this.brand = brand;
this.year = year;
}
public String toString() {
return "Car brand: " + brand + ", Year: " + year;
}
}
ObjectCreation.main(null);
Car brand: Tesla, Year: 2024
Car brand: Toyota, Year: 2020
Homework Hack 2
public class HeapVsStack {
public static void main(String[] args) {
int pages = 300;
int pagesCopy = pages;
Book b1 = new Book("Java Basics");
Book b2 = b1;
pages = 500;
b1.title = "Advanced Java";
System.out.println("Primitives:");
System.out.println("pages = " + pages);
System.out.println("pagesCopy = " + pagesCopy);
System.out.println("\nObjects:");
System.out.println("b1 = " + b1);
System.out.println("b2 = " + b2);
}
}
class Book {
String title;
Book(String title) {
this.title = title;
}
public String toString() {
return "Book title: " + title;
}
}
HeapVsStack.main(null);
Primitives:
pages = 500
pagesCopy = 300
Objects:
b1 = Book title: Advanced Java
b2 = Book title: Advanced Java