Loading
Understand how classes serve as blueprints and objects bring them to life at runtime.
Before the rise of object-oriented programming (OOP), software engineers wrote programs as long sequences of instructions—an approach known as procedural programming. As codebases grew from hundreds of lines to hundreds of thousands, procedural code became notoriously difficult to maintain, extend, and debug. Data and the functions that operated on that data were loosely coupled, making it easy for one part of a program to corrupt another part's state inadvertently. The fundamental insight that emerged in the 1960s was deceptively simple: organize programs around the real-world entities they model, bundling data and behavior together into self-contained units called objects.
The evolution from procedural to object-oriented thinking gave rise to a powerful question that sits at the heart of this lesson: if a class defines what something is and what it can do, how do we create individual, living instances of that class that hold their own unique data? Understanding the distinction between a class as a blueprint and an object as a concrete instance is the gateway to mastering Java and the AP Computer Science A exam.
In Java, the relationship between a class and an object mirrors the relationship between an architectural blueprint and the house built from it. A class is a programmer-defined data type that specifies the attributes (instance variables) and behaviors (methods) that its objects will have. An object is a specific instance of a class that occupies memory at runtime and holds its own copies of those attributes. The process of creating an object from a class is called instantiation, and it is accomplished in Java using the new keyword. Each object created from the same class shares the same structure—the same set of instance variables and methods—but maintains its own independent state.
new keyword. It lives in the heap memory and has its own copies of instance variables holding unique values.new is called. It initializes the object's instance variables. Its name always matches the class name and it has no return type.null. Calling a method on a null reference throws a NullPointerException at runtime.new) to produce an actual cookie you can eat (an object you can use).new Dog(...) call creates a separate object on the heap with its own instance variable values. The reference variables on the stack (dog1, dog2, dog3) store memory addresses that point to their respective objects. A reference set to null points to nothing.The diagram above illustrates the fundamental mechanism at work. The Dog class on the left defines the structure—three instance variables (name, age, breed) and two methods—but it holds no data of its own. Each invocation of new Dog(...) allocates fresh memory on the heap and invokes the constructor to populate the instance variables with concrete values. Notice that dog1, dog2, and dog3 share the same structure but contain completely different data—"Buddy" versus "Luna" versus "Max." The reference variables in the stack panel do not contain the objects themselves; they hold addresses (shown symbolically as 0x3A, 0x7F, 0xB2) that point to the objects in heap memory. This distinction between the reference and the object it references is essential for understanding assignment, equality, and parameter passing in Java.
In Java, creating an object involves a single statement that performs two distinct tasks: declaration of a reference variable and instantiation of the object. The general syntax is:
Consider the following concrete examples using Java's built-in String class and a custom Student class:
greeting stores the address of that object. (Note: Java also supports the shorthand String greeting = "Hello, AP CS!"; which uses the string pool, but the new form illustrates general object creation.)name, gradeLevel, and gpa. The reference s1 now points to the newly created Student object in memory.false for booleans, null for reference types).new expression evaluates to the memory address of the newly created object, which is stored in the reference variable.new Student("Bob") would call a one-parameter constructor, while new Student("Alice", 12, 3.9) calls the three-parameter version.One of the most common pitfalls for AP students is confusing the reference variable with the object itself. When you write Dog dog1 = new Dog("Buddy", 3, "Lab");, the variable dog1 is not the object—it is a reference that points to the object. This has profound implications for assignment and equality. When you execute Dog dog4 = dog1;, you do not create a second Dog; instead, dog4 and dog1 now both point to the same object in memory. This phenomenon is called aliasing, and it means that modifying the object through one reference is visible through the other.
Dog dog4 = dog1;, both references hold the same address (0x3A). Calling dog4.setAge(4) mutates the single object, so dog1.getAge() also returns 4.Because reference variables store addresses rather than data, the == operator compares addresses—it checks whether two references point to the same object, not whether two objects contain the same data. To compare the contents of two objects, use the .equals() method. For example, dog1 == dog4 evaluates to true because they are aliases, but if you create Dog dog5 = new Dog("Buddy", 3, "Labrador"), then dog1 == dog5 evaluates to false even though the data is identical, because they reside at different heap addresses.
| Expression | Result | Explanation |
|---|---|---|
dog1 == dog4 | true | Both reference the same object (aliased). |
dog1 == dog5 | false | Different objects, even with identical data. |
dog1.equals(dog5) | Depends on class | Returns true only if the class overrides equals() to compare field values. |
dog1 == null | false | dog1 references an object, so it is not null. |
Consider the following code that uses a Rectangle class with instance variables width and height, a constructor Rectangle(double w, double h), and methods getArea() and toString(). We want to trace through the following statements and determine what is printed.
Rectangle r1 = new Rectangle(4.0, 5.0); allocates a new Rectangle object on the heap with width = 4.0 and height = 5.0. The reference variable r1 stores the address of this object.Rectangle r2 = new Rectangle(3.0, 7.0); creates a separate Rectangle object with width = 3.0 and height = 7.0. This object occupies a different heap location than the first.Rectangle r3 = r1; does not create a new object. It copies the address stored in r1 into r3. Now both r1 and r3 reference the same Rectangle{4.0, 5.0} object.r1.getArea() returns 4.0 × 5.0 = 20.0. r2.getArea() returns 3.0 × 7.0 = 21.0. r1 == r3 evaluates to true because they share the same address. r1 == r2 evaluates to false because they reference different objects.Students preparing for the AP exam frequently encounter the same set of mistakes when working with objects and references. The table below catalogs these pitfalls alongside the correct approach, giving you a diagnostic checklist to consult when debugging your code or answering free-response questions.
| Pitfall | What Goes Wrong | Correct Approach |
|---|---|---|
Forgetting the new keyword | Declaring Dog d; without new leaves d as null. Calling d.bark() throws NullPointerException. | Always initialize with new ClassName(args) before using the reference. |
| Using == for content equality | s1 == s2 returns false even when both objects hold identical data, because == compares references. | Use .equals() for content comparison (especially with String objects). |
| Unintended aliasing | Assigning one reference to another creates a shared reference, not a copy. Mutating through one alias surprises code using the other. | Create a new object with the same data if you need an independent copy. |
| Wrong constructor arguments | Passing arguments in the wrong order or of the wrong type causes a compile-time error or, worse, silent logical bugs. | Match the number, type, and order of parameters exactly as defined in the constructor signature. |
| Calling methods on null | If a reference is null and you call a method on it, the program crashes at runtime with a NullPointerException. | Check for null before calling methods: if (obj != null). |
The class-and-object model you are learning for the AP exam forms the foundation for virtually every advanced topic in Java and software engineering. Understanding how objects work prepares you for inheritance (where a subclass extends a parent class, and objects of the subclass are also instances of the parent), polymorphism (where a reference of a parent type can point to an object of a subclass type), and interfaces (where multiple unrelated classes can share a common API). At the systems level, understanding heap allocation and references connects to garbage collection, memory management, and performance optimization—topics you will encounter in data structures and operating systems courses.
| AP CS A Concept | Advanced Extension | Why It Matters |
|---|---|---|
| Objects & instantiation | Design patterns (Factory, Singleton, Builder) | Patterns control how and when objects are created in large systems. |
| Reference variables | Garbage collection & memory management | When no reference points to an object, the JVM reclaims its memory automatically. |
| Constructors | Inheritance & super() chaining | Subclass constructors must invoke a superclass constructor, creating a chain of initialization. |
| Class as a type | Polymorphism & interfaces | A reference of type Animal can point to a Dog object—runtime behavior depends on the actual object type. |
| == vs .equals() | hashCode() contract & collections | HashMap and HashSet rely on consistent equals/hashCode implementations to locate objects. |
As you progress beyond the AP exam, you will find that the mental model of classes as blueprints and objects as instances is not merely a pedagogical simplification—it is the architectural foundation upon which frameworks like Spring, Android, and enterprise Java are built. Every web request in a Spring application, every Activity in an Android app, and every node in a data structure is an object instantiated from a class. Mastering this concept now creates a transferable mental framework that scales naturally to advanced coursework and professional software development.
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = s1;
What are the values of s1 == s2 and s1 == s3?public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public void translate(int dx, int dy) {
x += dx;
y += dy;
}
public String toString() {
return "(" + x + ", " + y + ")";
}
}
What is printed by the following code segment?
Point p1 = new Point(2, 3);
Point p2 = p1;
p2.translate(5, -1);
System.out.println(p1);BankAccount class has the following constructor and methods:
• BankAccount(String owner, double balance) — constructs an account with the given owner name and initial balance.
• void deposit(double amount) — adds amount to the balance.
• double getBalance() — returns the current balance.
Write a code segment that:
(a) Creates two BankAccount objects, one for "Alice" with $500.00 and one for "Bob" with $1200.00.
(b) Deposits $250.00 into Alice's account.
(c) Prints the balance of each account on separate lines.public class Roster {
private Student[] students;
private int count;
public Roster(int capacity) {
students = new Student[capacity];
count = 0;
}
/** Adds a student to the roster.
* Precondition: count < students.length
*/
public void addStudent(String name, int grade) {
// Part (a): implement this method
}
/** Returns the number of students in the given grade.
*/
public int countInGrade(int targetGrade) {
// Part (b): implement this method
}
}
The Student class has constructor Student(String name, int grade) and method int getGrade().
(a) Write the body of addStudent. It should create a new Student object and add it to the next available position in the array, then increment count.
(b) Write the body of countInGrade. It should iterate over the students in the roster and return the number whose grade matches targetGrade.A class is a blueprint that defines instance variables (state) and methods (behavior). An object is a concrete instance created by the new keyword, which allocates memory on the heap and invokes a constructor to initialize the object's state. Multiple objects can be instantiated from the same class, each with its own independent data. A reference variable stores the memory address of an object, not the object itself—assigning one reference to another creates an alias, not a copy.
The == operator compares references (addresses), while .equals() compares object content. A reference that has not been assigned to an object holds the value null, and calling a method on null triggers a NullPointerException. These foundational concepts—instantiation, reference semantics, aliasing, and null—form the basis for every object-oriented topic on the AP Computer Science A exam, from writing constructors and calling methods to understanding inheritance and polymorphism.
Keep learning with more lessons from the same subject.