# AP® Computer Science A 3.4 Constructors

Source: https://lockincs.com/ap-csa/unit-3/3-4-constructors/  
Last reviewed against the College Board Course and Exam Description (CED): 2026-11-12  
CED codes: 3.4.A, 3.4.A.1, 3.4.A.2, 3.4.A.3, 3.4.A.4, 3.4.A.5

An object's state is its attributes and their values at a given time, stored in the object's instance variables (a has-a relationship). A constructor sets the initial state: when it is called, memory is allocated for the object and a reference to it is returned. If you write no constructor, Java provides a no-parameter default constructor that sets instance variables to default values.

## What you will learn

- 3.4.A Develop code to declare instance variables for the attributes, to be initialized in the body of the constructors of a class.

## 1\. State: what an object has, right now

An object’s **state** is its attributes and their values at a given time. The state is defined by the instance variables that belong to the object 3.4.A.1. This is a **has-a relationship**: a player *has a* name, *has a* score and *has a* level 3.4.A.1.

```
public class Player
{
    private String name;
    private int score;
    private int level;

    /** Creates a player at level 1 with a score of 0 */
    public Player(String playerName)
    {
        name = playerName;
        score = 0;
        level = 1;
    }

    /** Creates a player at startLevel with a score of 0 */
    public Player(String playerName, int startLevel)
    {
        name = playerName;
        score = 0;
        level = startLevel;
    }

    public void addPoints(int points)
    {
        score += points;
        if (score >= 100)
        {
            level++;
            score -= 100;
        }
    }

    public String getName()
    {
        return name;
    }

    public int getScore()
    {
        return score;
    }

    public int getLevel()
    {
        return level;
    }

    public String toString()
    {
        return name + " L" + level + " " + score + " pts";
    }
}
```

```
Player ana = new Player("Ana");
System.out.println(ana);
ana.addPoints(70);
System.out.println(ana);
ana.addPoints(45);
System.out.println(ana);
```

Output:

```
Ana L1 0 pts
Ana L1 70 pts
Ana L2 15 pts
```

**Background:** `println(ana)` shows the text built by the class’s `toString` method. You will read `toString` in class code, but writing one is outside the AP® exam.

The state changes over time:

| Moment | name | score | level |
| --- | --- | --- | --- |
| After `new Player("Ana")` | “Ana” | 0 | 1 |
| After `addPoints(70)` | “Ana” | 70 | 1 |
| After `addPoints(45)` | “Ana” | 15 | 2 |

## 2\. Writing a constructor

A **constructor** sets the initial state of an object, and that should include an initial value for **every** instance variable 3.4.A.2. Constructor parameters, if there are any, provide the data used to initialize the instance variables 3.4.A.2.

When a constructor is called with `new`, memory is allocated for the object and the reference to the new object is returned 3.4.A.2. The variable stores that reference, not the object itself.

```
Player p1 = new Player("Ana");
Player p2 = new Player("Ben", 5);
System.out.println(p1.getLevel() + " " + p2.getLevel());
```

Output:

```
1 5
```

Memory after these lines:

```
p1 [ ref ] ---> Player object:  name "Ana"   score 0   level 1
p2 [ ref ] ---> Player object:  name "Ben"   score 0   level 5
```

`Player` has two constructors with different parameter lists (overloaded constructors). Java chooses the one whose parameters match the arguments.

**Watch out:** a constructor has the same name as the class and **no return type**. If you write `void`, Java treats it as a method, not a constructor:

```
public class Pet
{
    private String name;

    public void Pet(String petName)
    {
        name = petName;
    }
}

Pet cat = new Pet("Miso");
```

Compiler says:

```
error: constructor Pet in class Pet cannot be applied to given types;
```

## 3\. Mutable object parameters: store a copy

When a **mutable object** (an object whose state can change) is a constructor parameter, the instance variable should be initialized with a **copy** of the object. Then the instance variable does not hold a reference to the original object, and outside code cannot change the state of your object through the original 3.4.A.3.

Here is a mutable class:

```
public class Location
{
    private int row;
    private int col;

    public Location(int r, int c)
    {
        row = r;
        col = c;
    }

    public int getRow()
    {
        return row;
    }

    public int getCol()
    {
        return col;
    }

    public void moveTo(int r, int c)
    {
        row = r;
        col = c;
    }

    public String toString()
    {
        return "(" + row + ", " + col + ")";
    }
}
```

**Version 1 (risky):** the constructor stores the same reference.

```
public class Robot
{
    private Location home;

    public Robot(Location start)
    {
        home = start;
    }

    public String homeText()
    {
        return home.toString();
    }
}
```

```
Location spot = new Location(2, 3);
Robot bot = new Robot(spot);
spot.moveTo(9, 9);
System.out.println(bot.homeText());
```

Output:

```
(9, 9)
```

```
spot [ ref ] ---+
                +---> Location object: row 9, col 9
home [ ref ] ---+    (one object, two references)
```

**Version 2 (correct):** the constructor makes a new `Location` with the same values.

```
public class Robot
{
    private Location home;

    public Robot(Location start)
    {
        home = new Location(start.getRow(), start.getCol());
    }

    public String homeText()
    {
        return home.toString();
    }
}
```

```
Location spot = new Location(2, 3);
Robot bot = new Robot(spot);
spot.moveTo(9, 9);
System.out.println(bot.homeText());
```

Output:

```
(2, 3)
```

```
spot [ ref ] ---> Location object: row 9, col 9
home [ ref ] ---> Location object: row 2, col 3   (the robot's own copy)
```

`String` objects are immutable, so a constructor can store a `String` parameter directly: nobody can change that string.

## 4\. The default constructor and default values

When no constructor is written, Java provides a no-parameter constructor, called the **default constructor**, and the instance variables are set to **default values** according to their data types 3.4.A.4.

| Type of attribute | Default value 3.4.A.5 |
| --- | --- |
| `int` | `0` |
| `double` | `0.0` |
| `boolean` | `false` |
| any reference type (such as `String`) | `null` |

```
public class Settings
{
    private int volume;
    private double brightness;
    private boolean muted;
    private String theme;

    // no constructor written: Java provides Settings()

    public String toString()
    {
        return volume + " " + brightness + " " + muted + " " + theme;
    }
}
```

```
Settings s = new Settings();
System.out.println(s);
```

Output:

```
0 0.0 false null
```

**Watch out:** once you write any constructor, Java no longer provides the default constructor. `Player` has two constructors, but neither has zero parameters:

```
Player p = new Player();
```

Compiler says:

```
error: no suitable constructor found for Player(no arguments)
```

**Watch out:** a constructor that does not set an instance variable leaves it at its default value. A forgotten `String` is `null`, and calling a method on it later (such as `name.length()`) causes a `NullPointerException`.

## Common mix-ups

- Not true: A constructor needs the return type void. A constructor has no return type at all. If you write void, Java treats it as an ordinary method that happens to have the class name, and it is never called by new.
- Not true: Java always gives every class a no-parameter constructor. Java provides the default constructor only when you write no constructor. As soon as you write one, new ClassName() with no arguments works only if you wrote a no-parameter constructor yourself.
- Not true: Storing a parameter object in an instance variable makes a copy of it. Assigning a reference copies the reference, not the object. To protect a mutable object, the constructor must create a new object with the same values.

## In 30 seconds

- State = the object's attributes and their values at a given time; the object has-a each instance variable.
- A constructor sets the initial state and should give every instance variable an initial value.
- Calling a constructor allocates memory for the object and returns a reference to it.
- Constructor parameters provide the data used to initialize instance variables.
- For a mutable object parameter, store a copy of the object, not the original reference.
- No constructor written: Java provides a default constructor; int 0, double 0.0, boolean false, references null.

## Checkpoint: 5 practice questions

### Question 1

Consider the following class, which has no constructor. The code segment below the class appears in a method in another class. What is printed as a result of executing the code segment?

```java
public class Gadget
{
    private int count;
    private double weight;
    private boolean on;
    private String label;

    public String info()
    {
        return count + " " + weight + " " + on + " " + label;
    }
}

Gadget g = new Gadget();
System.out.println(g.info());
```

- A. Nothing is printed, because the class has no constructor
- B. 0 0 false null
- C. 0 0.0 false null
- D. 0 0.0 false

**Answer: C.** With no constructor written, Java provides a default constructor that sets each instance variable to its default value: `int` 0, `double` 0.0, `boolean` false and a reference type `null`. A `double` prints as 0.0, not 0. A `String` that was never set is `null`, not the empty string, so the word null is printed. The code compiles because the default constructor exists.

### Question 2

Consider the following incomplete class. The constructor is intended to set `artist` to `a`, `price` to `p` and `ticketsSold` to 0. Which of the following can replace `/* missing code */` so that the constructor works as intended?

```java
public class Concert
{
    private String artist;
    private double price;
    private int ticketsSold;

    public Concert(String a, double p)
    {
        /* missing code */
    }

    public String info()
    {
        return artist + " " + price + " " + ticketsSold;
    }
}
```

- A. `a = artist; p = price; ticketsSold = 0;`
- B. `artist = a; price = p; ticketsSold = 0;`
- C. `String artist = a; double price = p; ticketsSold = 0;`
- D. `artist = "a"; price = p; ticketsSold = 0;`

**Answer: B.** Constructor parameters provide the data, so each instance variable is assigned the matching parameter: `artist = a; price = p;`. Writing `a = artist` copies the other way and changes only the parameter. Declaring `String artist` creates new local variables, so the instance variables keep their default values. Writing `"a"` stores the letter a, not the value of the parameter.

### Question 3

Consider the following classes. The code segment below the classes appears in a method in another class. What is printed as a result of executing the code segment?

```java
public class Counter
{
    private int value;

    public Counter(int v)
    {
        value = v;
    }

    public int getValue()
    {
        return value;
    }

    public void increment()
    {
        value++;
    }
}

public class Scoreboard
{
    private Counter home;
    private Counter away;

    public Scoreboard(Counter h, Counter a)
    {
        home = h;
        away = new Counter(a.getValue());
    }

    public String show()
    {
        return home.getValue() + "-" + away.getValue();
    }
}

Counter x = new Counter(1);
Counter y = new Counter(2);
Scoreboard board = new Scoreboard(x, y);
x.increment();
y.increment();
System.out.println(board.show());
```

- A. 2-2
- B. 1-2
- C. 2-3
- D. 1-3

**Answer: A.** `home = h` stores the same reference as `x`, so incrementing `x` also changes `home` to 2. `away` was built as a new `Counter` copy with the value 2, so incrementing `y` does not affect it. The option 2-3 assumes both were stored as references, and 1-2 assumes both were copied.

### Question 4

The statement `Player p = new Player("Kai");` is executed. Which of the following best describes what happens?

- A. The constructor returns a copy of the new object's instance variables, which are stored in `p`
- B. The variable `p` is created, but memory for the object is allocated only when a method is called
- C. Memory is allocated for a new object, the constructor sets its initial state, and `p` gets its reference
- D. The constructor has return type `void`, so `p` stores the value `null`

**Answer: C.** Calling a constructor allocates memory for the object, runs the constructor body to set the initial state, and returns a reference that is stored in `p`. The variable does not hold copies of the instance variables. Memory is allocated at once, not later, and a constructor has no return type at all, not `void`.

### Question 5

Consider the following class. Which of the following statements, appearing in another class, compiles without error?

```java
public class Lamp
{
    private boolean on;

    public Lamp(boolean startOn)
    {
        on = startOn;
    }
}
```

- A. `Lamp a = new Lamp();`
- B. `Lamp c = Lamp(true);`
- C. `Lamp d = new Lamp("on");`
- D. `Lamp b = new Lamp(false);`

**Answer: D.** The only constructor takes one `boolean`, so `new Lamp(false)` matches. Because a constructor was written, Java does not provide a default constructor, so `new Lamp()` does not compile. A constructor must be called with `new`, and the argument "on" is a `String`, not a `boolean`.

## Questions students ask

**What does a constructor do in Java?**

A constructor sets the initial state of a new object, giving initial values to its instance variables. When it is called with new, memory is allocated for the object and a reference to the object is returned.

**What is a default constructor?**

It is the no-parameter constructor Java provides when a class has no constructor written. It sets each instance variable to the default value for its type: 0, 0.0, false or null.

**Why should a constructor copy a mutable object parameter?**

If the constructor stores the same reference, the caller can still change the object later and the change appears inside your object. Storing a new copy keeps the object's state under the class's control.

**Can a class have more than one constructor?**

Yes. Constructors can be overloaded: each has a different parameter list, and Java chooses the one that matches the arguments in the new expression.

---

© LockInCS, licensed CC BY-NC-ND 4.0. AP® is a trademark registered by the College Board, which is not affiliated with, and does not endorse, this website.
