Professional Documents
Culture Documents
Java (and all programming languages) split the memory available for the program
into two parts: the heap and the stack.
The stack is organized memory used for method calls. In Java, the default is to
set aside about 1MB for the stack (this can be changed when you launch Java).
The heap is unorganized memory used for data that needs to be more permanent. In
Java, all classes and objects are stored in the heap.
For every class your program uses, a class "object" is stored in the heap. The
class "object" stores:
1) The super class of the class
2) All methods (static and non-static) defined in the class.
3) All constructors of the class.
4) All static fields declared in the class.
5*) Any classes that are inside this class.
For every object (instance of a class) created by your program (e.g. by the new
operator), space for the instance is allocated in the heap.
The instance record stores:
1) The true type of the object.
2) All non-static fields of all the polymorphic types of the object. (this class,
the class this class extends, etc.)
The fields are stored in order starting from Object and down to the true type.
For example, we have a program that uses our Employee and HourlyEmployee classes.
In the heap, Java will place "objects" for the Employee and HourlyEmployee classes.
There will also be an "object" for the Object class since that class is extended by
Employee.
There will also be an "object" for String since String is used in these classes.
Creating an object:
Employee e1 = new Employee("Ishika")
Space is allocated for an instance in the heap. The instance object contains:
true type: the address of the Employee class "object"
the fields of Object: (whatever they are)
the fields of Employee: name, number, salary
Another example:
Employee e2 = new HourlyEmployee("Walter")
Polymorphism: An object is multiple types: every type from its true type up the
hierarchy to Object
true type (run-time type): what the object is (as created by new).
The true type never changes.
The true type of a value in a piece of code can often not be determined just by
reading the code. (This is why "run-time type" is often used. You can only know
what the true type is by running or tracing the code and seeing what gets stored.)
The true type determines what version of a method is executed.
current type (compile-time type): how the object is being used - what whas it
typecast to?
The current type constantly changes with each typecast.
You can always tell what the current type is by reading the code -> just look
at the variable declaration, any typecast, or the return value of the method (This
is why "compile-time type" is often used. The compiler can figure out the type by
reading the code.)
The current type determines whether a method call is legal and which fields can
be accessed.
Remember that the computer does not care about types (everything it sees is
binary numbers).
We, the programmer, use types as a safety feature. By setting a type, we are
indicating what the value represents, and the Java compiler (Java being a strictly
typed language) verifies that we are using the types correctly.
That means, the compiler verifies that we do not call a method unavailable to
the type nor access a field unavailable to the type.
Another example:
e2.getName()
The compiler uses the type of e2 to verify that the method getName with no input
is valid for that type.
Another example:
e1.earnsMoreThan(e2)
Java does the following:
1) Evaluates the left side of the dot to get an address. (Here it is stored in
e1.)
2) Goes to that address in the heap (it is an object), and goes to that
object's true type in the heap. (Here, it will go to the Employee class.)
3) Runs through the class's list of methods to find one that matches. (It will
find earnsMoreThan with a single Employee input.)
Note that "e" and "this" inside earnsMoreThan both have "current type" Employee
("e" because Employee is the type of the input parameter and "this" because we are
in the Employee class), but in this case the value stored in "e" has true type
HourlyEmployee.
As a result, it found HourlyEmployee's version of getSalary() and will use that
method.
This is why we used getSalary() instead of the salary field inside
earnsMoreThan.
If we used the salary field, since the current type of "this" is Employee, it
will only know about Employee's fields and will use Employee's salary field. But
with methods, the version of the true type is always run.
** The current type will be used by the compiler to determine of an instance method
call is legal for that type, but the true type version of
the method is always run. **
** The current type will determine the field or static method accessed by the code
**