AP CSA 3.4: Constructors
AP CSA 3.4: Constructors
A constructor runs once, at new, and its only job is to leave the object valid. Overload it and every version owes the same debt: set everything, or the language quietly sets it to zero for you.
A constructor runs once, when an object is created, and its job is to leave every attribute set. It has the same name as the class and no return type at all - not even void, because adding one turns it into an ordinary method and Java quietly uses the default constructor instead. A class may have several constructors as long as their parameter lists differ, which is overloading. Write no constructor and Java supplies a no-argument one that leaves numbers at 0, booleans at false and objects at null.
What you will learn
- Write a constructor with the right name, no return type, and a full set of assignments
- Explain what Java's default constructor does, and when you stop getting it
- State the default value of an int, a double, a boolean and an object reference
- Write overloaded constructors and say what makes each signature distinct
- Spot the reversed assignment and the parameter that shadows an attribute
- Check that every overload leaves the object completely initialised
Why this matters on the exam
Constructors are the second point on free-response question 2, every year. The rubric wording varies but the check does not: the reader looks for a constructor with the correct signature that assigns every instance variable the specification describes. Miss one attribute in one overload and the point goes.
On the multiple-choice side this topic is unusually mechanical, which makes it cheap marks. A constructor with void in front of it is no longer a constructor. A constructor whose assignment runs backwards reads an uninitialised field and stores nothing useful. A parameter with the same name as an attribute shadows it, so a bare assignment writes the parameter to itself and the object never changes. Each of those has a recognisable shape, and none of them produces a compiler error.
That last part is the reason this lesson matters more than it looks. Every failure here compiles and runs. The object simply comes out wrong, and the first evidence is a value of 0 or null somewhere far away from the constructor that caused it.
The problem this solves
A game lets you start as a nameless rookie, or pick a name, or pick a name and a starting level. Three ways in, one object at the end, and every one of them has to leave a character the rest of the game can handle. That is what overloaded constructors are for. The trap is that Java will happily build a half-initialized object for you: a field you forgot is not an error, it is a 0, a false, or a null, and it will not surface until something downstream behaves strangely.
Constructors: the only moment an object is born
A constructor runs exactly once per object, at new, and its whole job is to leave the object in a valid starting state. It has the same name as the class, it is always public, and it has no return type at all, not even void. Writing one is how you make sure an object never exists in a state your methods cannot handle.
The shape, and the one that appears for free
public class GameCharacter { private String name; private int level; // same name as the class, no return type public GameCharacter(String n, int lvl) { name = n; level = lvl; } } // write NO constructor and Java supplies // a no-argument one that sets nothing. // write ANY constructor and that free // one disappears.
| name | same as the class |
| return type | none, ever |
| access | always public |
| runs | once, at new |
GameCharacter(String n) and new GameCharacter() stops compiling. If you want both, write both.Overloading: several ways to be born
Two constructors can share a name because they differ in their signature, which is the ordered list of parameter types. Java picks the one whose signature matches the arguments at the call.
public GameCharacter() { name = "Rookie"; level = 1; } public GameCharacter(String n) { name = n; level = 1; } public GameCharacter(String n, int lvl) { name = n; level = lvl; }
| new GC() | the no-arg one |
| new GC("Nova") | the String one |
| new GC("Rex", 4) | the String, int one |
| chosen by | the signature |
What you do not set, Java sets for you
An instance variable the constructor never assigns is not garbage and it is not an error. It quietly takes its type's default.
private int count; // 0 private double rate; // 0.0 private boolean open; // false private String label; // null
| int | 0 |
| double | 0.0 |
| boolean | false |
| String / object | null |
false, a name that should say "Rookie" instead says null. Nothing crashes and nothing warns. If a value should not be zero or false, the constructor has to say so.Vocabulary
| Term | Meaning |
|---|---|
| Constructor | A public block with the same name as the class and no return type, run once when an object is created, to set its initial state. |
| Signature | A constructor's or method's name plus its ordered list of parameter types. This is what distinguishes overloads. |
| Overloaded constructors | Two or more constructors in one class with different signatures. The arguments at the call decide which runs. |
| Default constructor | The no-argument constructor Java supplies only when the class declares no constructor of its own. |
| Default value | What an instance variable holds when no constructor assigns it: 0 for int, 0.0 for double, false for boolean, null for String and other objects. |
| Initial state | The values of an object's instance variables immediately after its constructor finishes. |
| Derived attribute | An instance variable computed from others in the constructor, which therefore depends on the order of the assignments. |
Predict first, then check
count but never touches private boolean open;. What does open hold?health = 100 + 10 * (lvl - 1); with lvl of 4. What is health?Common misconceptions
Each of these is a real answer students give. Read the wrong version first and decide why it is wrong before you read the fix.
Giving the constructor a return type
public void Battery() { ... } looks like every other method, so it must be fine."
void it is an ordinary method that happens to share the class's name, and it never runs on new. Java then supplies the default constructor, so the object is built with every field at its default and no error is reported. A constructor has no return type at all.
Assuming the default constructor is always there
Rectangle(int w, int h), so new Rectangle() still works."
new Rectangle() stops compiling unless you write that overload yourself. This is why a specification listing three ways to build an object means three constructors, not two plus a freebie.
Writing the assignment backwards
startCharge = charge; and charge = startCharge; do the same thing."
null. Read every constructor assignment with the attribute on the left.
Letting a parameter shadow the attribute
charge, and charge = charge; sets the field."
charge = charge; assigns the parameter to itself and the attribute never changes. Until this arrives in 3.9, the fix is to name the parameter something different - startCharge, c, newCharge - which is what the AP subset expects at this point in the course.
Finishing the job in only one overload
See three constructors run
The same class, built three different ways. Watch which overload runs, what each one sets, and what a field that nobody assigns quietly becomes.
Live code editor
Eight problems, six scaffolded and two open-ended. Write Java and press Run to execute it. When you are ready, press Submit to test it against the expected output; the reference solution then appears underneath, next to your own code rather than on top of it. Hints are there if you are stuck, and attempts and hints are both tracked.
A rechargeable Battery. The methods are written for you; the two constructors are yours.
Attributes, already declared
- charge
- percent of charge, always 0 to 100
- cycles
- how many times this battery has been charged
Constructors to write
- Battery()
- a fresh battery: 100 percent, 0 cycles
- Battery(int startCharge)
- starts at startCharge with 0 cycles. Above 100 becomes 100, below 0 becomes 0.
Methods to fill in
- void recharge()
- full charge, and one more cycle
- int getCharge()
- reports the charge
- int getCycles()
- reports the cycle count
A Rectangle that remembers its own area. Three overloaded constructors, and the stored area has to be right whichever one was used.
Attributes, already declared
- width, height
- the two sides
- area
- width times height, correct at all times
Constructors to write
- Rectangle()
- a 1 by 1 unit square
- Rectangle(int s)
- an s by s square
- Rectangle(int w, int h)
- a w by h rectangle
Methods to fill in
- int getArea()
- reports the stored area
- int getWidth(), int getHeight()
- report the sides
- boolean isSquare()
- true when the sides are equal
Constructor Arcade
Six quick rounds. Read the class and the client code, then type the final value. These are the six constructor traps the exam keeps returning to: which overload runs, what a forgotten field defaults to, and what the order of the lines does to a derived value.
public class A {
private int n;
public A() { n = 5; }
public A(int v) { n = v; }
public int get() { return n; }
}
A a = new A();
int x = a.get();
public class B {
private int n;
private int twice;
public B(int v) { n = v; twice = n * 2; }
public int get() { return twice; }
}
B b = new B(9);
int x = b.get();
public class C {
private int n;
private int twice;
public C(int v) { twice = n * 2; n = v; }
public int get() { return twice; }
}
C c = new C(9);
int x = c.get();
public class D {
private int health;
public D(int lvl) { health = 100 + 10 * (lvl - 1); }
public int get() { return health; }
}
D d = new D(6);
int x = d.get();
public class E {
private int a;
private int b;
public E() { a = 3; b = 4; }
public E(int v) { a = v; }
public int get() { return a + b; }
}
E e = new E(10);
int x = e.get();
public class F {
private int side;
private int area;
public F() { side = 1; area = 1; }
public F(int s) { side = s; area = s * s; }
public F(int w, int h) { side = w; area = w * h; }
public int get() { return area; }
}
F f = new F(3, 8);
int x = f.get();
Multiple choice
Predict your answer before reading the options. Watch for the qualifier words. After you answer, the rationale explains every distractor.
public class Crate {
private int items;
private int capacity;
private int spare;
public Crate(int c) {
capacity = c;
spare = capacity - items;
}
public int getSpare() {
return spare;
}
}
Crate c = new Crate(12);
System.out.println(c.getSpare());
public class Stopwatch {
private int seconds;
private boolean running;
public Stopwatch() {
seconds = 60;
running = true;
}
public Stopwatch(int s) {
seconds = s;
}
}
public class Badge {
private String owner;
private int level;
public Badge(String o) {
owner = o;
level = 1;
}
public String getOwner() { return owner; }
public int getLevel() { return level; }
}
I. new Badge("Ana") creates a Badge with level 1
II. Badge declares exactly one constructor
III. new Badge() compiles and creates a Badge with owner null
public class Sample {
// constructors go here
}
public class Bin {
private int capacity;
private int count;
// constructors go here
}
public class Sample {
private int mass;
public Sample(int mass) {
mass = mass;
}
public int getMass() {
return mass;
}
}
public class Tile {
private int size;
private boolean placed;
private String label;
public int getSize() {
return size;
}
public boolean isPlaced() {
return placed;
}
public String getLabel() {
return label;
}
}
Tile t = new Tile();
System.out.println(t.getSize());
System.out.println(t.isPlaced());
System.out.println(t.getLabel());
I. new Crate(2, 3) II. new Crate(4) III. new Crate()
public class Pack {
// which pair cannot coexist?
}
public class Bin {
private int capacity;
public Bin(int cap) {
cap = capacity;
}
public int getCapacity() {
return capacity;
}
}
public class Order {
private int total;
public Order() { ... }
public Order(int n) { ... }
public Order(int n, int rate) { ... }
}
public class Pack {
private int size;
private int weight;
public Pack() {
size = 2;
weight = 10;
}
public Pack(int s) {
size = s;
weight = size * 5;
}
public int total() {
return size + weight;
}
}
Pack p = new Pack(4);
Pack q = new Pack();
System.out.println(p.total() + q.total());
FRQ Practice
Free-response question 2 is Class Design, and constructors are where most of its second point lives. A reader is checking one thing above all: does every constructor leave the object completely set up? An overload that forgets one attribute produces an object that is legal, compiles, and is quietly wrong.
This one is worth 4 points. The three constructors are yours to write; the method headers are given, because writing methods from nothing is 3.5. Route all three through the private helper rather than repeating the pricing rule, which is the same instinct as 3.3's clamp helper.
A streaming service sells three plans by the month, with a discount for a year or more.
| Call | Result |
|---|---|
| new Subscription() | basic, 1 month, 500 cents |
| new Subscription("pro") | 1 month of pro, 1500 cents |
| new Subscription("plus", 12) | 900 x 12 = 10800, less 10 percent = 9720 |
| new Subscription("gold", 3) | an unknown plan is stored as basic: 1500 cents |
| new Subscription("pro", 11) | 11 months misses the discount: 16500 |
Scoring: 1 point for three constructors with distinct parameter lists, 1 point for all three leaving every attribute set, 1 point for the pricing including the unknown-plan fallback, and 1 point for the discount applying at exactly 12 months and not at 11.
A streaming service sells three Subscription plans by the month, with a discount for a year or more.
Attributes, already declared
- plan
- "basic", "plus" or "pro"
- months
- how many months were bought
- totalCents
- the whole cost, worked out when the object is built
Pricing
- basic 500
- per month
- plus 900
- per month
- pro 1500
- per month
Constructors to write
- Subscription()
- basic, 1 month
- Subscription(String p)
- plan p, 1 month
- Subscription(String p, int m)
- plan p, m months. Precondition: m is 1 or more.
total - total * 10 / 100, so 11 months misses it.Choose your lane
Support
- Reread the Code and Memory panels
- Editor problems 1 to 3 with hints on
- Retry the quiz until 80%
- Use the FRQ method shell
Core
- All 8 editor problems
- Full game run
- The 12-question quiz once
- The FRQ connection
Challenge
- Open-ended problems 7 and 8 with no hints
- Rewrite one loop a different way
- Extend the FRQ
- Lead a class trace
Summary
A constructor is the method that runs when an object is created. It carries the class's name, takes no return type, and is always public in this course. Its single responsibility is that the object is completely set up by the time new hands it back.
If a class declares no constructor at all, Java supplies a default constructor that takes no arguments and leaves every attribute at its default: 0 for numeric types, false for boolean, and null for any object reference. Declaring even one constructor removes that free one, which is why a specification describing three ways to build an object needs three written constructors.
Several constructors can share the name as long as their parameter lists differ - overloading - and the compiler picks by the arguments at the call site. The failure that costs points is an overload that initialises only some attributes, because the resulting object is legal and quietly wrong. Two smaller traps have the same character: an assignment written backwards, and a parameter named the same as the attribute it was meant to fill. Neither is a compiler error. Both leave a default value where a real one should be.
Key takeaways
- A constructor has the class's name and no return type, not even
void. - It runs once, on
new, and must leave every attribute set. - Write no constructor and Java gives you a no-argument one; write any and that free one is gone.
- Defaults are 0 for numbers,
falsefor boolean,nullfor object references. - Overloads are distinguished by their parameter lists, and each is responsible for the whole object.
- Assignment is right to left: the attribute goes on the left, always.
- A parameter sharing an attribute's name shadows it; rename the parameter until 3.9.
Frequently asked questions
What is the difference between a constructor and a method?
A constructor has the same name as the class, has no return type at all, and runs exactly once when the object is created with new. A method has its own name, declares a return type even if that type is void, and is called whenever you like. Writing void in front of something you meant to be a constructor turns it into a method with a confusing name, and it will never run on new.
What happens if I do not write a constructor?
Java supplies a default constructor that takes no arguments and does nothing, so every attribute keeps its default value: 0 for int, 0.0 for double, false for boolean, and null for any object reference such as a String. As soon as you declare any constructor of your own, that free one is gone, and a call to new ClassName() only compiles if you wrote a no-argument version yourself.
What are overloaded constructors?
Two or more constructors in the same class, distinguished by their parameter lists - different numbers of parameters, or different types. The compiler chooses by the arguments at the call site, so new Rectangle(5) and new Rectangle(3, 8) reach different constructors. Each one has to leave the object fully initialised on its own; they are alternatives, not stages.
Why does my constructor compile but leave everything at zero?
Almost always one of two reasons. Either the assignment is backwards - startCharge = charge; copies the empty attribute into the parameter instead of the other way round - or the parameter has the same name as the attribute, so charge = charge; assigns the parameter to itself. Neither is an error, so the only symptom is an object holding 0 or null.
Can one constructor call another?
In full Java yes, with this(...), but that is outside the AP CSA subset and you will not see it on the exam. The technique you want instead is the one used here: put the shared setup in a private helper method and have every constructor call it. Same benefit - the rule is written once - and it stays inside what the exam expects.
Do constructors have to be public?
For this course, yes. The 2025 CED states it directly: constructors are always designated public, just as classes always are. Private constructors exist in real Java for specialised patterns, but they are not part of the AP subset, so treat a private constructor in a multiple-choice question as a red flag rather than a design you should imitate.
Related lessons
Unit 3: Class Creation
All 9 lessons in this unit. You are on 3.4.
- 3.1 Abstraction and Program Design
- 3.2 Impact of Program Design
- 3.3 Anatomy of a Class
- 3.4 Constructors
- 3.5 Methods: How to Write Them
- 3.6 Methods: Passing and Returning Object References
- 3.7 Class Variables and Methods
- 3.8 Scope and Access
- 3.9 The this Keyword
Test yourself on this unit
The rest of the course
Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]