Java Object-Oriented Fundamentals, Memory Allocation, Packages, and Reference Mechanics
Fundamental Memory Behavior of Primitive Data Types
- Primitive data types (predefined data types) cannot evaluate to
null. - Declaring a primitive variable such as
int x; reserves a memory cell on the stack designated as x. - Uninitialized primitive memory cells contain unspecified leftover bits or bytes from previous allocations; the Java system guarantees no default values.
- Rule: Primitive variables must never be accessed or evaluated prior to explicit value assignment.
- Combining declaration and initialization into a single statement, such as
int y = 0;, allocates box y and stores value 0 directly inside it.
Reference Variables and Null Pointer Exceptions
- Declaring a reference variable (e.g.,
Random r;) creates a memory variable cell designed to store a memory address. - An uninitialized reference variable box defaults to containing
null, visually represented as a zero with a slash through it (∅). - Referring to an unassigned reference variable describes a null reference or null feature.
- Executing methods or operations on a reference variable holding
null triggers a NullPointerException. - A standing course challenge dictates that if any student completes an entire semester without encountering a
NullPointerException, the class receives a day off (a challenge maintained continuously over a 4-year period). - Initializing a reference variable via
r = new Random(); requests heap memory allocation, receives the generated heap memory address, and stores that address inside reference cell r. - Reference variables can be declared independently of immediate instantiation and assigned later to alternative reference variables or new heap allocations.
Runtime Stack versus Memory Heap Architecture
- Memory storage in Java is divided into the runtime stack and the memory heap.
- All primitive variables and reference variables (which hold memory addresses) reside on the runtime stack.
- All actual object data and fields allocated via reference types reside in the memory heap.
- Primitive types possess operators (
+, -, *, /, %) but do not possess behaviors or methods. - Reference types possess behaviors (methods), accessed using the dot (
.) member access operator.
Object Creation, Reassignment, and Memory Leaks
- Sequentially reassigning a single reference variable demonstrates memory allocation behavior:
- Declaration:
Random r; creates one single reference variable r on the stack. - First allocation:
r = new Random(); allocates the first object in the heap and stores its address in r. - Second allocation:
r = new Random(); allocates a second object in the heap, updating r with the new address and severing the link to the first object. - Third allocation:
r = new Random(); allocates a third object in the heap, updating r with the new address and severing the link to the second object.
- Across these operations, exactly one reference variable (
r) exists, pointing exclusively to the third heap object. - Unreferenced heap objects whose reference links have been severed are termed orphans.
- Allocating memory in the heap that can no longer be accessed by the program constitutes a memory leak.
Java Garbage Collection and Real-Time Systems Constraints
- Java features an automated memory cleanup system known as the Garbage Collector.
- Periodically during program execution, the operating system and Java runtime execute the Garbage Collector.
- The Garbage Collector scans the memory heap for orphans (allocated memory lacking active reference variables) and reclaims their memory back to the heap.
- If memory leaks accumulate in a system without collection, available memory is exhausted, causing the program to stop execution.
- Garbage Collection execution timing is entirely non-deterministic and cannot be explicitly predicted or scheduled by the programmer.
- Due to non-deterministic Garbage Collector pauses, Java is never used for real-time embedded systems or time-critical applications (such as automobile Anti-lock Braking Systems / ABS, where an unexpected Garbage Collector pause during braking would produce dangerous delays).
- Java is optimal for non-time-sensitive applications, desktop software, and mobile phone applications.
- Programming languages serve as targeted tools, selected based on specific application requirements.
Java Standard Packages and Import Declarations
- Java organizes library classes into packages, which represent the default organizational structure for Java libraries.
java.lang: Default package automatically imported into every Java program without explicit statements, providing core classes like String and Math.- Graphical User Interface (GUI) development packages:
Swing: First generation GUI framework introduced for drawing graphical components such as boxes and circles.AWT (Abstract Window Toolkit): Graphical package developed alongside and following Swing (utilized in Lab 3).
java.text: Package containing utility classes for numerical and textual output formatting.java.util: Package containing general utility classes, including Scanner and Random.java.io: Package containing classes required for reading and writing file input and output.- Import statements must appear at the very top of source code files prior to the
public class declaration (e.g., import java.util.Scanner;). - Java import mechanics differ significantly from C/C++: while C/C++
#include statements perform literal copy-paste inclusion of library code into source code, the Java compiler only loads classes that are actively referenced. - Using wildcard imports (e.g.,
import java.util.*;) carries no memory overhead or file size penalty compared to explicit class imports.
Class Instantiation, Constructors, and the SimpleDate Class
- Evaluating the data type of a variable like
IndependenceDay yields a reference to SimpleDate (or SimpleDate). - Java is strongly typed; reference assignments require type compatibility. A reference to
SimpleDate cannot be assigned to a reference for Random or Scanner. - Executing
SimpleDate defaultDate = new SimpleDate(); performs object construction:- Parentheses indicate invocation of external executable logic or code blocks.
- A method sharing the exact identifier as the class type is a constructor, responsible for constructing the heap object.
- A constructor call with empty parentheses
() invokes the default constructor, populating object fields with standard default initial values (e.g., date values set to 01/01/2000). - Parameterized constructors accept explicit input arguments, such as
new SimpleDate(7, 4, 1776) or new SimpleDate(5, 15, 2030), initializing fields for month, day, and year (month=7, day=4, year=1776; month=5, day=15, year=2030).
- Object memory structure consists of a stack box storing the memory address and a heap structure containing state variables (month, day, year).
Application Programming Interfaces (API) and Reference Aliasing
- Application Programming Interface (API): Formal documentation detailing available classes, methods, constructors, parameters, and default values. Integrated Development Environments (IDEs) present API details through hover inspection tooltips.
- Aliasing: Occurs when two or more distinct reference variables store the exact same heap memory address (e.g.,
hireDate and promotionDate pointing to a single object). - When reference aliases exist, modifying or clearing one reference variable does not trigger Garbage Collection on the target object, as long as another active reference variable points to it.
Value Comparison Operators versus the Equals Method
- The assignment operator
= assigns values, whereas the double equal operator == executes literal value comparisons. - The
== operator strictly compares the raw values held inside activation frame variables on the runtime stack. - For primitive variables,
== compares raw numeric or primitive values. - For reference variables,
== compares stored heap memory addresses rather than internal object data fields. - Given two donkey objects
Mabel and Bernice, evaluating Mabel == Bernice yields false because the variables store addresses of distinct heap objects. - To compare internal field values of objects, the
.equals() method must be invoked: mabel.equals(bernice).
Trace Analysis of Code Execution, Type Conversions, and String Concatenation
- Trace analysis of specific execution statements:
- Execution at line 15 evaluates numeric expressions resulting in explicit printed outputs (e.g., truncation/formatting resulting in
666666667 or 1.0). - Evaluation of line 22 string concatenation:
- The
+ operator functions as string concatenation when operating on string operands. - The expression `