A constructor is special code that runs automatically the moment an object is created, and its main job is to set up that object with valid starting values before anything else can use it.
Why constructors exist
Without a constructor, an object starts out with default values, such as zero for numbers or null for objects, and has to be filled in manually afterward, one field at a time. A constructor lets an object arrive fully formed in a single step, the moment it is created.
Writing a constructor
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}A constructor shares its name with the class and has no return type, not even void. Using it is straightforward:
Person p = new Person("Ann", 30);What this actually means
Inside the constructor, the parameter and the field are both called name, which would otherwise be ambiguous. Writing this.name specifically means the field belonging to the current object, distinguishing it from the parameter of the same name sitting right next to it. Without this, the line name = name would simply assign the parameter to itself and leave the field untouched.
Constructor overloading
A class can offer several constructors with different parameter lists, letting an object be created in more than one way:
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this(name, 0);
}
}The second constructor calls the first using this(name, 0), avoiding repeated setup logic and giving age a sensible default of zero when only a name is supplied.
The default constructor
If a class defines no constructor at all, Java quietly supplies an empty one for free. The moment even one constructor is written by hand, however, that free default disappears, and any other way of creating the object needs its own explicit constructor.
A note on immutability
Constructors are also the foundation of immutable objects, ones whose fields are set once and never changed afterward. Marking fields final and only assigning them inside the constructor guarantees an object cannot be modified after creation, which makes it inherently safer to share across different parts of a program, including across multiple threads.