Full Java constructors tutorial
Java is an object-oriented programming language.
To create objects and meaningfully initialize them, a developer must use a Java constructor. Constructors are a critical part of software development in Java.
That's why software developers must understand the following:
- Why Java constructors are needed.
- How Java constructors work.
- What Java constructors do.
- How to code different types of constructors.
- How constructors behave at runtime.
This full Java constructors tutorial quickly provides a deep understanding of this important programming concept.
What is a constructor in Java?
A Java constructor is a special method that lets developers simultaneously create instances of classes and initialize instance variables.
The syntax of a Java constructor is simple. For the most part, it follows the same rules as Java methods with the following exceptions:
- A Java constructor has the same name as the class.
- A constructor in Java does not have a return type.
- A constructor can't be static, volatile or final.
Why are Java constructors needed?
The goal of a constructor in Java is to simply provide convenient ways for a developer to create an instance of a class and initialize its instance variables.
For example, the following class named Car has one boolean property to indicate whether the car is a stick shift or not. The class contains a zero-argument constructor that initializes this value to true.
public class Car {
boolean stickShift;
Car() {
stickShift = true;
}
}
How do you call a constructor in Java?
In an application, a developer could create an instance of the Car class and print out the value of this stickShift property as follows:
var bmw = new Car();
System.out.println("This car is a manual: " + bmw.stickShift);
Because the default constructor initialized the stickShift variable to false, this code prints out the following:
This car is a manual: true
What is a default constructor in Java?
While a constructor is required to create an instance of a class, developers aren't required to add a constructor to every class they create.
If a class does not have an explicitly defined constructor, Java provides a default, zero-argument constructor for you.
The drawback to Java's default constructor is that its initializations are fairly meaningless:
- Reference types are initialized to null.
- Primitive number types are initialized to 0.
- Primitive boolean values are initialized to false.
Default constructor example
For example, we can rewrite the Java constructor example above without any constructor:
public class Car {
boolean stickShift;
}
Then, we create an instance of the class using the default constructor:
var bmw = new Car();
System.out.println("This car is a manual: " + bmw.stickShift);
However, the output is different because the default initialization of a boolean value is false, not true.
The output of our example is as follows:
This car is a manual: false
What is a parameterized constructor in Java?
The default constructor is perfect to perform the exact function that it describes: assign defaults.
But in real-world Java applications, the program itself should decide how an object is initialized. That's why most Java classes provide non-default constructors, also known as parameterized constructors.
For example, we might want the calling program to tell us if the car is a stick shift or not. To do this, we add a parameterized constructor that allows the calling program to set the instance's stickShift property.
public class Car {
boolean stickShift;
Car(boolean stick) {
stickShift = stick;
}
}
How do you use non-default Java constructors?
With the non-default constructor, we can create multiple instances with custom values for the stickShift property.
var viper = new Car(true);
var tesla = new Car(false);
System.out.println("This Viper is a manual: " + viper.stickShift);
System.out.println("This tesla is a manual: " + tesla.stickShift);
When this code runs, the output reflects the different values for each instance of the Car class:
This Viper is a manual: true
This Tesla is a manual: false
Why do default constructors disappear?
When a non-default constructor is added to a class, the default constructor is no longer available.
The JVM sees a non-default constructor and assumes the developer has a very specific idea about what data should be provided when an instance of that class is created. To respect this fact, it removes the ability to call the default constructor and create objects with default values.
However, if a zero-argument constructor still makes sense, a class can always explicitly add one.
Example of an overloaded constructor in Java
Here you can see the Car class has both an explicitly declared, zero-argument constructor along with a parametrized Java constructor:
public class Car {
boolean stickShift;
Car() {
stickShift = true;
}
Car(boolean stick) {
stickShift = stick;
}
}
As developers build programs that use the Car class, they can decide whether it's more sensible to call the default constructor or the non-default constructor.
var viper = new Car();
var tesla = new Car(false);
When multiple constructors are added to a class, it is known as constructor overloading, and it follows the same rules as method overloading in Java.
Java constructors tutorial
Constructors in Java are an extensive topic.
Advanced knowledge of Java constructors includes a deep dive into a variety of peripheral topics such as the following:
- The this() method to call other constructors.
- The super() method to call parent constructors.
- How the JVM allocates memory during a constructor call.
- The use of private constructors, singletons and factories.
However, those advanced topics are much easier to digest when a developer learns the most fundamental concepts pertaining to Java constructors, all of which were covered in this Java constructors tutorial.
Cameron McKenzie has been a Java EE software engineer for 20 years. His current specialties include Agile development, DevOps and container-based technologies such as Docker, Swarm and Kubernetes.