Constructors in Java
Initializing objects reliably with constructors, overloaded constructors, and constructor chaining.
3 min read
A constructor is special method-like code that runs when an object is created with new, and its job is to set the object up in a valid initial state. Without one, you're stuck assigning every field manually after creation, which is easy to forget and easy to get wrong.
Writing a constructor
A constructor has the same name as the class, and no return type — not even void.
public class Dog {
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}Dog rex = new Dog("Rex", 3);Now every Dog is guaranteed to have a name and age set at the moment it's created — there's no window where the object exists in a half-initialized state.
The default constructor
If you don't write any constructor at all, Java silently provides a no-argument default constructor that does nothing but create the object with all fields at their default values. The moment you write any constructor yourself, that free default disappears — if you still want a no-arg option alongside your custom one, you have to write it explicitly.
Overloading constructors
Just like regular methods, constructors can be overloaded to offer several ways to create an object:
public class Dog {
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog(String name) {
this.name = name;
this.age = 0; // default age when not specified
}
}Dog rex = new Dog("Rex", 3);
Dog puppy = new Dog("Puppy"); // age defaults to 0Constructor chaining with this(...)
To avoid repeating initialization logic across overloaded constructors, one constructor can call another in the same class using this(...) as its first statement:
public class Dog {
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog(String name) {
this(name, 0); // delegates to the two-argument constructor
}
}This keeps the actual field-assignment logic in one place, so a future change (like adding validation) only needs to happen once. Constructor chaining, along with super(...) for calling a parent class's constructor (covered in the next lesson), is one of the small habits that separates clean object-oriented Java from code that merely compiles.
Validating in the constructor
Because the constructor is the one place every object's creation passes through, it's a natural spot to reject invalid state immediately rather than letting it slip in silently:
public class Dog {
String name;
int age;
public Dog(String name, int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative: " + age);
}
this.name = name;
this.age = age;
}
}Failing fast here means a bad age value is caught the moment a Dog is created, with a clear error message pointing at the actual cause — instead of surfacing later as a confusing bug somewhere else in the program that happens to read age.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.