Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java constructors and validated state

Last updated: 29 Sept 20264 min read
tutorial
By AITrove Editorial

A constructor initializes a new object and can reject inputs that would leave it unusable.

Working model

Require the identifier at creation. The constructor below validates the supplied value before storing it. This keeps every successfully created ticket usable without a later initialize call.

Code

Java
public class SupportTicket {
    private final String ticketId;

    public SupportTicket(String ticketId) {
        if (ticketId == null || ticketId.trim().isEmpty()) {
            throw new IllegalArgumentException("ticketId is required");
        }
        this.ticketId = ticketId;
    }

    public String id() {
        return ticketId;
    }
}

A constructor has the class name and no return type. this.ticketId distinguishes the field from the parameter. final prevents reassignment of this field after construction; it does not make every object referenced by a final field immutable.

Cost and design choices

Validation adds work once per creation. That is often cheaper than requiring every operation to recover from missing state. Keep expensive I/O out of constructors when failures need a separate retry policy.

Keep partially built objects private

Do not publish this to another thread or callback before construction finishes. The observer can see an object whose invariants have not been established. Calling an overridable method from a constructor can also dispatch to subclass code before subclass initialization completes.

Validate related fields together. Two fields can each be individually valid while their combination is invalid, such as an end timestamp before a start timestamp. Constructor success should mean the complete object state is usable.

Connected lessons

Continue with Java encapsulation and object ownership, Java Tutorial.

Common Mistakes

Adding a return type turns the declaration into a method. Do not call overridable methods from constructors: subclass state may not yet be initialized. Avoid storing mutable input collections without deciding who owns later edits.

Validate before the object escapes

Constructor chaining should lead to one place that establishes the state contract. Duplicated validation in several overloads can drift until one constructor permits a state another rejects. A factory can name distinct creation policies without making callers guess which positional argument combination applies.

Avoid registering this with an external listener or starting a worker while construction is still in progress. Another component can then observe fields before the invariant is established. Finish creation, then let an explicit owner publish the object or start its resources.

Construction can allocate more than the outer object: copied collections, parsed metadata and acquired resources all contribute cost. If the constructor can fail after acquiring a resource, cleanup needs an explicit scope. A simple immutable value constructor should not quietly own a long-lived connection or executor.

java
constructors
Storage details