Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 2
This month, you have three questions to answer:
Last month, I asked you to trace the initialization process through the Employees source code below (assume that java Employees starts the program):
Employees.java
// Employees.java
class Employee
{
private String name;
private double salary;
static int count;
static double bonus;
Employee (String name, double salary)
{
this.name = name;
this.salary = salary;
if (this instanceof Accountant)
this.salary += bonus;
}
static
{
// Pretend to load bonus from a database.
bonus = 500.0;
}
{
if (count > 5)
bonus = 0.0;
count++;
}
String getName ()
{
return name;
}
double getSalary ()
{
return salary;
}
}
class Accountant extends Employee
{
Accountant (String name, double salary)
{
super (name, salary);
}
}
class Employees
{
public static void main (String [] args)
{
String [] names =
{
"John Doe",
"Jane Smith",
"Jack Jones",
"Bob Smyth",
"Alice Doe",
"Janet Jones"
};
double [] salaries =
{
40000.0,
50000.0,
30000.0,
37500.0,
52000.0,
47000.0
};
for (int i = 0; i < names.length; i++)
if (i < 3)
{
Employee e = new Employee (names [i], salaries [i]);
System.out.println ("Name = " + e.getName ());
System.out.println ("Salary = " + e.getSalary ());
}
else
{
Accountant a = new Accountant (names [i], salaries [i]);
System.out.println ("Name = " + a.getName ());
System.out.println ("Salary = " + a.getSalary ());
}
}
}
When run, Employees produces the following output:
Name = John Doe Salary = 40000.0 Name = Jane Smith Salary = 50000.0 Name = Jack Jones Salary = 30000.0 Name = Bob Smyth Salary = 38000.0 Name = Alice Doe Salary = 52500.0 Name = Janet Jones Salary = 47500.0
How does Employees achieve that output? The following numbered list takes you through the program's execution and itemizes all initialization
steps until the last Accountant object finishes initializing:
Employees.class into memory, and the JVM's byte code verifier verifies all byte code instructions in that class.
Employees declares no class fields, the JVM does not allocate memory for class fields and zeroes all bits comprising that memory.
Employees's main() method. Memory is allocated on the method call stack for local variables names, salaries, i, e, and a.
main() method's byte code instructions create a names array and a salaries array. References to those arrays (whose memory exists on the JVM's object heap) assign to local variables names and salaries.
for loop statement byte code instructions begin to execute. Zero assigns to local variable i.
i's value (0) is less than names.length's (6), for executes the if decision statement.
if evaluates i < 3. Because i's value (0) is less than 3, the byte code instructions comprising Employee e = new Employee (names [i], salaries [i]); start to execute.
Employee in those instructions and has its class loader load Employee.class. The JVM's byte code verifier then verifies all byte code instructions comprising that class.
Employee declares two class fields (count and bonus), the JVM allocates memory for those class fields and zeroes all bits comprising that memory.
Employee's <clinit> method. That method assigns 500.0 to bonus.Employee object's name and salary instance fields, and zeroes all bits comprising that memory. A reference to that object's memory is placed in a temporary
stack location.
<init> method corresponding to Employee(String name, double salary).
<init> method first calls Object's no-argument <init> method, which does nothing and subsequently returns.
<init> method next executes an if decision statement's byte code instructions that evaluate count > 5. Because count currently contains 0, 0.0 does not assign to bonus.
<init> method next executes the equivalent of count++. count now contains 1.
<init> method next assigns the reference in its name parameter to the name field and the double-precision floating-point value in its salary parameter to the salary field.
<init> method uses the byte code equivalent of instanceof to see if the current object is an instance of Accountant. Because the object is not such an instance, nothing further happens and <init> exits.
Employee object's reference from the temporary stack location and assigns it to local variable e.
System.out.println() method calls result in calls to Employee's getName() and getSalary() methods for the object referenced by e. Those methods return the appropriate name and salary values, which subsequently print.
for loop statement increments i (which becomes 1), and checks to see if i's value is still less than names.length's (6) -- which it still is. Therefore, the if decision statement executes a second time.
i contains 1 and 2) repeat previous steps, let's continue where i contains 3.
if evaluates i < 3. Because i's value equals 3, the byte code instructions comprising Accountant a = new Accountant (names [i], salaries [i]); start to execute.
Accountant in those instructions and has its class loader load Accountant.class. The JVM's byte code verifier then verifies all byte code instructions comprising that class.
Accountant declares no class fields, the JVM does not allocate memory for class fields and zeroes all bits comprising that memory.
Accountant contains no class initializers, there is no <clinit> method to execute.
Accountant object's name and salary instance fields (which are located in the Employee layer), and zeroes all bits comprising that memory. A reference to the Accountant object is placed in a temporary stack location.
<init> method corresponding to Accountant(String name, double salary).
<init> method first calls Employee's two-argument <init> method.
Employee's <init> method calls Object's no-argument <init> method, which does nothing and subsequently returns.
Employee's <init> method next executes the if decision statement that evaluates count > 5. Because count currently contains 3, 0.0 does not assign to bonus.
Employee's <init> method next executes the equivalent of count++. count now contains 4.
Employee's <init> method next assigns the reference in its name parameter to the name field and the double-precision floating-point value in its salary parameter to the salary field.
Employee's <init> method uses the byte code equivalent of instanceof to see if the current object is an instance of Accountant. Because the current object is such an instance, the contents of bonus (500.0) are added to the salary field.
Employee's <init> method exits to Accountant's <init> method.
Accountant's <init> method has nothing further to do, so it exits.
Accountant object's reference from the temporary stack location and assigns it to local variable a.
System.out.println() method calls result in calls to Accountant's inherited getName() and getSalary() methods for the object referenced by a. Those methods return the appropriate name and salary values, which subsequently print.
for loop statement increments i (which becomes 4), and checks to see if i's value is still less than names.length's (6) -- which it still is. Therefore, the if decision statement executes a second time.
i contains 4 and 5) repeat previous steps, let's continue where i contains 6.
i contains 6, the for loop statement, followed by main(), exits. Before main() exits, the JVM releases memory for the local variables from the method call stack.