How do I set initial object values using a constructor in Java?

A constructor initializes an object when you create it using the new keyword. You can pass values to the constructor to set the object’s initial state.

In this example, you will create a Book class with a constructor that accepts a title and an author.

Source code

public class ConstructorExample {
    void main() {
        Book firstBook = new Book("Learning Java", "Alice");
        Book secondBook = new Book("Exploring Java", "Bob");

        firstBook.printDetails();
        IO.println();
        secondBook.printDetails();
    }
}

class Book {
    private final String title;
    private final String author;

    Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    void printDetails() {
        IO.println("Title: " + title);
        IO.println("Author: " + author);
    }
}

Explanation

The Book class declares two fields:

private final String title;
private final String author;

The private modifier limits direct access to these fields to the Book class. The final modifier means each field can be assigned only once.

The constructor receives the initial field values:

Book(String title, String author) {
    this.title = title;
    this.author = author;
}

A constructor has the same name as its class and does not declare a return type, not even void.

Here, the parameter names match the field names. The keyword this refers to the current object, so this.title identifies the field while title identifies the parameter.

For example:

this.title = title;

This statement assigns the value of the title parameter to the current object’s title field.

The following expression creates a book and passes two arguments to its constructor:

new Book("Learning Java", "Alice")

The constructor sets the new object’s title to "Learning Java" and its author to "Alice".

Each call to new Book(...) creates a separate object with its own field values.

Run the example

Compile and run the file:

javac ConstructorExample.java
java ConstructorExample

Output

Title: Learning Java
Author: Alice

Title: Exploring Java
Author: Bob

What happens to the default constructor?

Java provides a default constructor only when a class declares no constructors.

Since this Book class declares a constructor with two parameters, the following expression causes a compilation error:

new Book()

To create a Book, supply the title and author, or explicitly add a constructor with no parameters.

How do I Initialize Fields Before Calling super() in Java 25?

Java 25 includes JEP 513: Flexible Constructor Bodies. This feature changes a long-standing rule: before Java 22, the call to super(...) or this(...) had to be the very first statement in a constructor. Starting with Java 25, you can execute statements before the explicit constructor invocation — including initializing your own instance fields.

This is especially useful when a field’s value must be ready before the superclass constructor runs (for example, if the superclass calls an overridden method that reads that field).


The Old Restriction (Pre-Java 22)

public class Child extends Parent {
    private final int value;

    public Child(int input) {
        // Compile error before Java 22:
        // "call to super must be first statement in constructor"
        this.value = input * 2;
        super(computeSomething(input));
    }
}

The Java 25 Way: Prologue Before super(...)

With flexible constructor bodies, the constructor is split into two regions:

  1. Prologue — statements that run before super(...) or this(...).
  2. Epilogue — the usual constructor body that runs after.

Example 1: Initializing a Field Before super()

public class Parent {
    public Parent() {
        // Calls a method that subclasses may override
        describe();
    }

    protected void describe() {
        System.out.println("Parent describing");
    }
}

public class Child extends Parent {
    private final String label;

    public Child(String label) {
        // Java 25: initialize field BEFORE super()
        this.label = label;
        super();
    }

    @Override
    protected void describe() {
        // Safe: 'label' is already assigned, no NPE
        System.out.println("Child label = " + label);
    }
}

Before Java 25, label would still be null when Parent‘s constructor called the overridden describe(). Now you can assign it first.


The Prologue Rules You Must Follow

Inside the prologue (code before super(...) / this(...)), the compiler enforces strict rules to keep things safe:

Allowed Not Allowed
Assign to fields declared in this class Read fields of this
Validate / transform constructor arguments Call instance methods on this
Compute values, throw exceptions, use if, switch, loops, try Use this or super as a value
Call static methods Access inherited (superclass) fields

Example 2: Combining Validation and Field Init

public class Rectangle {
    protected final int area;

    public Rectangle(int area) {
        this.area = area;
    }
}

public class Square extends Rectangle {
    private final int side;

    public Square(int side) {
        // Prologue: validate, then initialize own field, then call super
        if (side <= 0) {
            throw new IllegalArgumentException("side must be positive");
        }
        this.side = side;          // assigning own field is allowed
        super(side * side);        // explicit constructor invocation
        // Epilogue starts here — 'this' is fully available
        System.out.println("Created Square with side=" + side + ", area=" + area);
    }
}

Example 3: Why This Matters — Fixing the “Leaked this” Problem

public abstract class Shape {
    public Shape() {
        render(); // calls subclass override during construction
    }
    protected abstract void render();
}

public class Circle extends Shape {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius; // set before super() runs render()
        super();
    }

    @Override
    protected void render() {
        // Now 'radius' has its intended value, not 0.0
        System.out.println("Rendering circle with radius " + radius);
    }
}

Compiling and Running on Java 25

Since JEP 513 is a final feature in Java 25, no --enable-preview flag is required:

javac --release 25 Child.java Parent.java
java Child

Key Takeaways

  • You can now place statements — including assignments to your own fields — before super(...) or this(...).
  • The prologue cannot read this or call instance methods; it can only write to fields of the current class.
  • Exactly one explicit constructor invocation (super(...) or this(...)) is still required (implicitly or explicitly).
  • This feature is final in Java 25 — no preview flags needed.

This cleanly resolves cases where a subclass field needed to exist before the parent constructor ran, without resorting to static helpers or awkward factory methods.

How do I invoke superclass constructor?

This example shows you how to use the super keyword to call a superclass constructor. The Female class constructor calls its superclass constructor and initializes its own initialization parameters. The call to the superclass constructor must be done in the first line of the constructor in the subclass.

package org.kodejava.example.fundamental;

public class Human {
    private String gender;
    private int age;

    public Human(String gender) {
        this.gender = gender;
    }
}

To call a superclass constructor we call super(). In the case below we call the superclass constructor with one string variable as a parameter.

package org.kodejava.example.fundamental;

public class Female extends Human {
    private String hairStyle;

    public Female(String hairStyle, String gender) {
        super(gender);
        this.hairStyle = hairStyle;
    }
}

How do I create constructors for a class?

Every class in Java has a constructor. constructor is a method that is used to create an instance or object of the class. Every time you create an instance, you must invoke a constructor.

If you do not create a constructor method of your class, the compiler will build a default one. A default constructors is a constructor that accept no argument.

Things to be noted when you declare a constructor:

  • Constructor must have the same name as the class in which they are declared.
  • Constructor can’t have a return type.
  • Constructor can have access modifier.
  • Constructor can take arguments.
  • Constructor can’t be marked static.
  • Constructor can’t be marked final or abstract.
package org.kodejava.basic;

public class ConstructorDemo {
    private String arg;
    private int x;
    private int y;

    public ConstructorDemo() {
    }

    public ConstructorDemo(String arg) {
        this.arg = arg;
    }

    public ConstructorDemo(int x) {
        this.x = x;
    }

    public ConstructorDemo(int x, int y) {
        this.y = y;
    }
}

class RunConstructor {
    public static void main(String[] args) {
        // Change the default constructor from private to public in
        // the ConstructorDemo class above then call the statement 
        // below. It will create an instance object cons0 without 
        // any error.
        ConstructorDemo cons0 = new ConstructorDemo();

        // Change the default constructor back to private, then call 
        // the statement below. ConstructorDemo() is not visible 
        // because it declared as private.
        ConstructorDemo cons1 = new ConstructorDemo();

        // invoke Constructor(String arg)
        ConstructorDemo cons2 = new ConstructorDemo("constructor");

        // invoke public Constructor(int x)
        ConstructorDemo cons3 = new ConstructorDemo(1);

        //invoke Constructor(int x, int y)
        ConstructorDemo cons4 = new ConstructorDemo(1, 2);
    }

}

How do I define constructor in enum type?

In the following example you’ll see how to add a constructor to an enum type value. Because an enum is just another class type it can have constructors, fields and methods just like any other classes. Below we define a constructor that accept a string value of color code. Because our enum now have a new constructor declared we have to define the constant named value as RED("FF0000"), ORANGE("FFA500"), etc.

In Java enumeration expanded beyond just as a named constants. Because enum is a class type we can add methods, fields and constructors to the enum type as you can see in the example below.

package org.kodejava.basic;

public enum Rainbow {
    RED("FF0000"),
    ORANGE("FFA500"),
    YELLOW("FFFF00"),
    GREEN("008000"),
    BLUE("0000FF"),
    INDIGO("4B0082"),
    VIOLET("EE82EE");

    private final String colorCode;

    // The constructor of Rainbow enum.
    Rainbow(String colorCode) {
        this.colorCode = colorCode;
    }

    /**
     * Get the hex color code.
     *
     * @return hex color code
     */
    public String getColorCode() {
        return colorCode;
    }
}
package org.kodejava.basic;

public class EnumConstructor {
    public static void main(String[] args) {

        // To get all values of the Rainbow enum we can call the
        // Rainbow.values() method which return an array of
        // Rainbow enum values.
        for (Rainbow color : Rainbow.values()) {
            System.out.println("Color = " + color.getColorCode());
        }
    }
}