Reference Guide for Stack Tracing Java
2025-05-13
FYI
• Only a single color is required for memory diagrams, different colors are used (and order written into
code) for greater clarity in this document
1 Basic Java
public static void main(String[] args) {
int anInt = 10;
double aDouble = 5.8;
boolean Boolean = true;
String aString = "6.3";
anInt = 20;
}
• variable changes result in previous values being crossed out and new ones written in so that progression
can be seen
1
2 Function calls
2.1 Return value
public static double multiplyByTwo(double input) {
double x = input * 2;
return x;
}
public static void main (String[] args) {
double x = 7.0;
double result = multiplyByTwo(x);
result = multiplyByTwo(result);
[Link](result);
int y = 3;
}
• each function call is put in its own stack frame
• variables created after the function call appear further down the stack
• IO stands for input/output and is where any command line user input or outputs in terms of print
statements appear
2
2.2 No return value
public static double printValue(int a) {
int temp = n+2;
[Link]("temp == " + temp);
}
public static void main (String[] args) {
printValue(4);
}
3
3 For loops
3.1 Basic
public static void main (String[] args) {
int x = 4;
for (int i = 1; i < 5; i++) {
[Link]("i == " + i);
}
}
3.2 Scoped Variable
public static void main (String[] args) {
int x = 4;
for (int i = 1; i < 5; i++) {
int temp = i + 2;
}
}
• scoped variables within the loop are crossed out after the loop completes
4
4 ArrayLists
public static void main (String[] args) {
ArrayList<Integer> arr1 = new ArrayList<>();
for (int x = 0; x < 4; x++) {
[Link](x);
}
[Link](arr1);
ArrayList<Integer> arr2 = arr1;
[Link](arr2);
}
• note that the assignment statement for arr2 assigns the memory address and does not do a deep copy
– this point is emphasized for newer programmers
• memory addresses all start with 0x to indicate that they are hexadecimal numbers.
– heap addresses are typically given 3 digit numbers
– numbers are typically written in decimal as it is easier for students to grasp at first (as they are
not familiar with hexadecimal, this detail will be corrected in later courses)
– numbers are randomly generated and just must agree on the stack and heap
5
4.1 Passed to functions
public static int sum(ArrayList<Integer> arrIn) {
int out = 0;
for (int x = 0; x < [Link](); x++) {
out += [Link](x);
}
return out;
}
public static void main (String[] args) {
ArrayList<Integer> arr1 = new ArrayList<>();
for (int x = 0; x < 4; x++) {
[Link](x);
}
[Link](arr1);
ArrayList<Integer> arr2 = arr1;
[Link](arr2);
int total = sum(arr1);
[Link]("total: " + total);
}
• when passing variables to functions as arguments the value on the stack associated with the variable
name is the argument to the function that sets the parameter
• the dashed lines around index indicate that it is a scoped variable that only exists while the loop exists
6
5 HashMaps
public static void main (String[] args) {
HashMap<String, Integer> bills = new HashMap<>();
[Link]("Allen", 17);
[Link]("Diggs", 14);
for (String keys: [Link]()) {
[Link](keys);
}
}
• HashMaps are like dictionaries in python
• we loop through them in a manner more similar to loops in python
• note that the loop still has scoped variables like the previous for loop
7
6 Recursion
6.1 Standard Recursion
public static int computeGeometricSum(int n) {
if (n > 0) {
int result = computeGeometricSum(n - 1);
result += n;
return result;
} else {
return 0;
}
}
public static void main (String[] args) {
int result = computeGeometricSum(3);
}
• each new call of cGS is performed in a new color
– returned values are kept in the color of the method that returns it
8
6.2 Tail Recursion
public static int computeGeometricSumTail(int n, int total) {
if (n > 0) {
return computeGeometricSum(n - 1, total + n);
} else {
return total;
}
}
public static int cGSTHelper(int n) {
return computeGeometricSumTail(n, 0);
}
public static void main (String[] args) {
int result = cGSTHelper(3);
}
• each new call of cGST is performed in a new color
– returned values are kept in the color of the method that returns it
• Note that the returns go to the previous function’s return and not a variable
– this is why the memory of a stack frame can be released before the following recursive function
call finishes
(Solution on next page)
9
10
7 Classes
public class Player {
private double xLoc;
private double yLoc;
private int maxHP;
private int HP;
private int damageDealt;
public Player(double xLoc, double yLoc, int maxHP) {
[Link] = xLoc;
[Link] = yLoc;
[Link] = maxHP;
[Link] = maxHP;
[Link] = 4;
}
public int getHP() {
return [Link];
}
public void takeDamage(int damage) {
[Link] -= damage;
}
public void attack(Player otherPlayer) {
[Link]([Link]);
}
public void move(double dx, double dy) {
[Link] += dx;
[Link] += dy;
}
public static void main(String[] args) {
Player player1 = new Player(0.0, 0.0, 10);
Player player2 = new Player(7.0, -4.0, 10);
[Link](-6.5, 3.4);
[Link](player1);
}
}
11
12
8 Inheritance
public class GameItem {
private double xLoc;
private double yLoc;
public GameItem(double xLoc, double yLoc) {
[Link] = xLoc;
[Link] = yLoc;
}
public void move(double dx, double dy) {
[Link] += dx;
[Link] += dy;
}
}
public class Teleporter extends GameItem {
private double dx;
private double dy;
public Teleporter(double xLoc, double yLoc, double dx, double dy) {
super(xLoc, yLoc);
[Link] = dx;
[Link] = dy;
}
public static void main(String[] args) {
Teleporter t = new Teleporter(2, 2, 3, 3);
[Link](2, 3);
}
}
13
14
9 Polymorphism
public class A {
protected int a;
public A(int a) {
this.a = a;
}
}
public class B extends A{
private int b;
public B(int b) {
super(b);
this.b = b*2;
}
}
public class C extends A{
private int c;
public C(int a, int c) {
super(a);
this.c = c;
}
}
public class RunABC {
public static void main(String[] args) {
A a = new A(1);
A b = new B(2);
A c = new C(3, 4);
}
}
15
16