1.5. Practice Exercises

Exercise 1: Person Class
Person Class

Consider the code for a Person class below, which is used throughout this activity.

 1public class Person {
 2
 3   private String name;
 4   private int age;
 5
 6   public Person(String name, int age) {
 7      this.name = name;
 8      this.age = age;
 9   } // Person
10
11   public String getName() {
12       return this.name;
13   } // getName
14
15   public void setName(String name) {
16       this.name = name;
17   } // setName
18
19   public int getAge() {
20       return this.age;
21   } // getAge
22
23   public void setAge(int age) {
24       this.age = age;
25   } // setAge
26
27} // Person
Question 1

Answer the following questions about the Person class:

  1. Identify the class's instance variables. How many instance variables are there?

  2. Identify the class's constructors. How many constructors are there?

  3. Identify the class's methods. How many methods are there?

  4. Which methods declare local variables? Which do not?

Note

Method parameters are considered local variables.

Solution
  1. name and age – (2)

  2. public Person(String name, int age) – (1)

  3. getName(), setName(String name), getAge(), and setAge(int age) – (4)

  4. The setName(String name) and setAge(int age) methods declare 1 local variable each, and the other methods do not declare any local variables. The constructor, which can be considered a special method, declares 2 local variables.

Question 2

Draw a diagram that depicts what the program's memory looks like after executing the code below.

Person nobody = null;
Person susan = new Person("Susan", 23);
Solution
Java program memory state. 1 stack frame; 2 heap objects.Stack frame: main:6 Person nobody: null Person susan: reference to object 903 Heap object 904: String@904 (length 5) : "Susan" Heap object 903: Person@903 String name: reference to object 904 int age: 23{"summary":"Java program memory state. 1 stack frame; 2 heap objects.","sections":[{"heading":"Stack frame: main:6","items":["Person nobody: null","Person susan: reference to object 903"]},{"heading":"Heap object 904: String@904 (length 5)","items":[": \"Susan\""]},{"heading":"Heap object 903: Person@903","items":["String name: reference to object 904","int age: 23"]}]}main:6PersonnobodynullPersonsusan903String@904 (length 5)"Susan"Person@903Stringname904intage23

Final captured memory state. [download] [open]

Question 3

Draw a memory map diagram depicting the state of the variables after the first half of the code below executes. Once your memory map is complete, write down what the output of the second half should be.

 4// first half
 5Person nobody = null;
 6Person susan = new Person("Susan", 23);
 7Person bill = new Person("Bill", 22);
 8Person p = bill;
 9
10// second half
11System.out.println(nobody);
12System.out.println(susan.getName());
13System.out.println(bill.getAge());
14System.out.println(p.getAge());
Solution
Java program memory state. 1 stack frame; 4 heap objects.Stack frame: main:15 Person nobody: null Person susan: reference to object 933 Person bill: reference to object 934 Person p: reference to object 934 Heap object 935: String@935 (length 5) : "Susan" Heap object 933: Person@933 String name: reference to object 935 int age: 23 Heap object 936: String@936 (length 4) : "Bill" Heap object 934: Person@934 String name: reference to object 936 int age: 22{"summary":"Java program memory state. 1 stack frame; 4 heap objects.","sections":[{"heading":"Stack frame: main:15","items":["Person nobody: null","Person susan: reference to object 933","Person bill: reference to object 934","Person p: reference to object 934"]},{"heading":"Heap object 935: String@935 (length 5)","items":[": \"Susan\""]},{"heading":"Heap object 933: Person@933","items":["String name: reference to object 935","int age: 23"]},{"heading":"Heap object 936: String@936 (length 4)","items":[": \"Bill\""]},{"heading":"Heap object 934: Person@934","items":["String name: reference to object 936","int age: 22"]}]}main:15PersonnobodynullPersonsusan933Personbill934Personp934String@935 (length 5)"Susan"Person@933Stringname935intage23String@936 (length 4)"Bill"Person@934Stringname936intage22

Final captured memory state. [download] [open]

Question 4

Draw a new memory diagram that takes into consideration the new code in the middle. After that, write down the output of the print statements near the bottom.

 4// these four lines have not changed
 5Person nobody = null;
 6Person susan = new Person("Susan", 23);
 7Person bill = new Person("Bill", 22);
 8Person p = bill;
 9
10// new code
11susan.setName("Bill");
12bill.setName("Susan");
13
14// print statements
15System.out.println(susan.getName());
16System.out.println(bill.getName());
17System.out.println(p.getName());
18System.out.println(nobody);
Solution

The interactive visualization stepper below shows the state of memory before and after the name modifications, as well as the accumulated console output after all print statements execute:

Step 1 of 3: line 11
Java program memory state. 1 stack frame; 4 heap objects.Stack frame: main:11 Person nobody: null Person susan: reference to object 916 Person bill: reference to object 917 Person p: reference to object 917 Heap object 904: String@904 (length 5) : "Susan" Heap object 916: Person@916 String name: reference to object 904 int age: 23 Heap object 918: String@918 (length 4) : "Bill" Heap object 917: Person@917 String name: reference to object 918 int age: 22{"summary":"Java program memory state. 1 stack frame; 4 heap objects.","sections":[{"heading":"Stack frame: main:11","items":["Person nobody: null","Person susan: reference to object 916","Person bill: reference to object 917","Person p: reference to object 917"]},{"heading":"Heap object 904: String@904 (length 5)","items":[": \"Susan\""]},{"heading":"Heap object 916: Person@916","items":["String name: reference to object 904","int age: 23"]},{"heading":"Heap object 918: String@918 (length 4)","items":[": \"Bill\""]},{"heading":"Heap object 917: Person@917","items":["String name: reference to object 918","int age: 22"]}]}main:11PersonnobodynullPersonsusan916Personbill917Personp917String@904 (length 5)"Susan"Person@916Stringname904intage23String@918 (length 4)"Bill"Person@917Stringname918intage22

Memory state at the breakpoint on line 11. [download] [open]

> (no output yet)

>_ Console Output

Java program memory state. 1 stack frame; 4 heap objects.Stack frame: main:15 Person nobody: null Person susan: reference to object 916 Person bill: reference to object 917 Person p: reference to object 917 Heap object 918: String@918 (length 4) : "Bill" Heap object 916: Person@916 String name: reference to object 918 int age: 23 Heap object 904: String@904 (length 5) : "Susan" Heap object 917: Person@917 String name: reference to object 904 int age: 22{"summary":"Java program memory state. 1 stack frame; 4 heap objects.","sections":[{"heading":"Stack frame: main:15","items":["Person nobody: null","Person susan: reference to object 916","Person bill: reference to object 917","Person p: reference to object 917"]},{"heading":"Heap object 918: String@918 (length 4)","items":[": \"Bill\""]},{"heading":"Heap object 916: Person@916","items":["String name: reference to object 918","int age: 23"]},{"heading":"Heap object 904: String@904 (length 5)","items":[": \"Susan\""]},{"heading":"Heap object 917: Person@917","items":["String name: reference to object 904","int age: 22"]}]}main:15PersonnobodynullPersonsusan916Personbill917Personp917String@918 (length 4)"Bill"Person@916Stringname918intage23String@904 (length 5)"Susan"Person@917Stringname904intage22

Memory state at the breakpoint on line 15. [download] [open]

> (no output yet)

>_ Console Output

Java program memory state. 1 stack frame; 4 heap objects.Stack frame: main:19 Person nobody: null Person susan: reference to object 916 Person bill: reference to object 917 Person p: reference to object 917 Heap object 918: String@918 (length 4) : "Bill" Heap object 916: Person@916 String name: reference to object 918 int age: 23 Heap object 904: String@904 (length 5) : "Susan" Heap object 917: Person@917 String name: reference to object 904 int age: 22{"summary":"Java program memory state. 1 stack frame; 4 heap objects.","sections":[{"heading":"Stack frame: main:19","items":["Person nobody: null","Person susan: reference to object 916","Person bill: reference to object 917","Person p: reference to object 917"]},{"heading":"Heap object 918: String@918 (length 4)","items":[": \"Bill\""]},{"heading":"Heap object 916: Person@916","items":["String name: reference to object 918","int age: 23"]},{"heading":"Heap object 904: String@904 (length 5)","items":[": \"Susan\""]},{"heading":"Heap object 917: Person@917","items":["String name: reference to object 904","int age: 22"]}]}main:19PersonnobodynullPersonsusan916Personbill917Personp917String@918 (length 4)"Bill"Person@916Stringname918intage23String@904 (length 5)"Susan"Person@917Stringname904intage22

Memory state at the breakpoint on line 19. [download] [open]

Bill
Susan
Susan
null

>_ Console Output

Note

You may be surprised by the fact that this compiles, runs without crashing, and produces output, given that nobody is used in the last print statement and the value of nobody is null.

It's okay to print null. This value is only a problem when you try to use it as a calling object.

Question 5

Using the updated memory map you drew for the last question, write down the output of the code below.

// these four lines have not changed
Person nobody = null;
Person susan = new Person("Susan", 23);
Person bill = new Person("Bill", 22);
Person p = bill;

// these four lines have not changed
susan.setName("Bill");
bill.setName("Susan");

// ignore the other print statements from earlier
// ...
System.out.println(nobody.getName());
Solution

This program crashes at runtime with a NullPointerException when nobody.getName() is executed because nobody holds the value null and does not refer to any valid object in memory:

Java program memory state. 1 stack frame; 4 heap objects.Stack frame: main:12 Person nobody: null Person susan: reference to object 963 Person bill: reference to object 964 Person p: reference to object 964 Heap object 936: String@936 (length 4) : "Bill" Heap object 963: Person@963 String name: reference to object 936 int age: 23 Heap object 935: String@935 (length 5) : "Susan" Heap object 964: Person@964 String name: reference to object 935 int age: 22{"summary":"Java program memory state. 1 stack frame; 4 heap objects.","sections":[{"heading":"Stack frame: main:12","items":["Person nobody: null","Person susan: reference to object 963","Person bill: reference to object 964","Person p: reference to object 964"]},{"heading":"Heap object 936: String@936 (length 4)","items":[": \"Bill\""]},{"heading":"Heap object 963: Person@963","items":["String name: reference to object 936","int age: 23"]},{"heading":"Heap object 935: String@935 (length 5)","items":[": \"Susan\""]},{"heading":"Heap object 964: Person@964","items":["String name: reference to object 935","int age: 22"]}]}main:12PersonnobodynullPersonsusan963Personbill964Personp964String@936 (length 4)"Bill"Person@963Stringname936intage23String@935 (length 5)"Susan"Person@964Stringname935intage22

Final captured memory state. [download] [open]

Exercise 2: SalaryAccount Class
SalaryAccount Class

You should assume the class below exists and is in scope for the questions in this subsection:

Listing 1.5 in SalaryAccount.java
 1public class SalaryAccount {
 2
 3   private int hours;
 4   private double rate;
 5
 6   public SalaryAccount(int hours, double rate) {
 7      // assume appropriate error handling...
 8      this.hours = hours;
 9      this.rate = rate;
10   } // SalaryAccount
11
12} // SalaryAccount
Question 1

Draw the memory map that represents the state of the variables after the following code executes:

SalaryAccount acct = new SalaryAccount(8, 20.0);
Solution

Your memory map should look similar to the following:

Java program memory state. 1 stack frame; 1 heap object.Stack frame: main:5 SalaryAccount acct: reference to object 930 Heap object 930: SalaryAccount@930 int hours: 8 double rate: 20.0{"summary":"Java program memory state. 1 stack frame; 1 heap object.","sections":[{"heading":"Stack frame: main:5","items":["SalaryAccount acct: reference to object 930"]},{"heading":"Heap object 930: SalaryAccount@930","items":["int hours: 8","double rate: 20.0"]}]}main:5SalaryAccountacct930SalaryAccount@930inthours8doublerate20.0

Final captured memory state. [download] [open]

Question 2

Draw the memory map that represents the state of the variables after the following code executes:

4SalaryAccount acct1 = new SalaryAccount(8, 20.0);
5SalaryAccount acct2 = new SalaryAccount(10, 22.5);
6SalaryAccount acct3 = new SalaryAccount(6, 18.75);
Solution

Your memory map should look similar to the following:

Java program memory state. 1 stack frame; 3 heap objects.Stack frame: main:7 SalaryAccount acct1: reference to object 941 SalaryAccount acct2: reference to object 942 SalaryAccount acct3: reference to object 943 Heap object 941: SalaryAccount@941 int hours: 8 double rate: 20.0 Heap object 942: SalaryAccount@942 int hours: 10 double rate: 22.5 Heap object 943: SalaryAccount@943 int hours: 6 double rate: 18.75{"summary":"Java program memory state. 1 stack frame; 3 heap objects.","sections":[{"heading":"Stack frame: main:7","items":["SalaryAccount acct1: reference to object 941","SalaryAccount acct2: reference to object 942","SalaryAccount acct3: reference to object 943"]},{"heading":"Heap object 941: SalaryAccount@941","items":["int hours: 8","double rate: 20.0"]},{"heading":"Heap object 942: SalaryAccount@942","items":["int hours: 10","double rate: 22.5"]},{"heading":"Heap object 943: SalaryAccount@943","items":["int hours: 6","double rate: 18.75"]}]}main:7SalaryAccountacct1941SalaryAccountacct2942SalaryAccountacct3943SalaryAccount@941inthours8doublerate20.0SalaryAccount@942inthours10doublerate22.5SalaryAccount@943inthours6doublerate18.75

Final captured memory state. [download] [open]