A constructor in Java looks like a method but does not return any value and does not have any return type, not even void
. It is called automatically whenever an object of the class is created, not by the compiler, but by the Java runtime environment. Therefore, a constructor is considered a special method.
The name of the constructor must be the same as the name of the class in which it is defined. A constructor contains a block of code that initializes the object, and this code is executed each time an object of that class is created.
How to Create a Constructor in Java
- The constructor name must be the same as the class name in which it is defined.
- A constructor does not have a return type, not even
void
.
Below is an example of creating a constructor:
class Car {
String color;
int year;
// Constructor to initialize values
Car() {
color = "Red";
year = 2020;
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car();
System.out.println("Color: " + car1.color + ", Year: " + car1.year);
}
}
In this program, the constructor Car()
has the same name as the class Car
, which is a requirement for constructors in Java. Inside the constructor, the variables color
and year
are initialized with the values "Red"
and 2020
, respectively, when the object is created.
The program then prints the values of the car1
object’s color
and year
attributes.
Why We Use Constructor in Java?
There are two common approaches for initializing object fields. The first approach is:
car1.color = "Red";
car1.year = 2020;
In this approach, we assign values to the object’s fields directly. While this works, it can become time-consuming and tedious if the number of fields or objects is large. Manually setting each field individually for multiple objects is inefficient and prone to errors.
The second approach is:
car1.setData("Red", 2020);
car2.setData("Red", 2020);
This assumes we have a setData
method in the Car
class. With this approach, we can set the object fields more efficiently than assigning each field individually. However, this approach can still become inconvenient if there are many objects to initialize, especially if we need to call the method for each object.
To solve the problem of manually initializing object fields, the constructor is used. A constructor allows us to initialize the object’s fields at the time of object creation, making it a more efficient and clean solution. Instead of setting each field individually after creating the object, constructors let you set initial values directly when the object is instantiated. This is why constructors are commonly used in Java.
Types of Constructors in Java
There are only two types of constructors in Java:
- Default Constructor
- Parameterized Constructor
1. Default Constructor:
When you do not explicitly define a constructor in your class, Java automatically provides a default constructor. This constructor does not have any parameters, and it does not contain any code inside the body (unless you explicitly define it). Its sole purpose is to allow the creation of an object from the class.
class Car {
String color; // Instance variable (default value = null)
int year; // Instance variable (default value = 0)
// Default constructor (implicitly created if no constructor is defined)
// If you do not define this, Java provides it automatically.
public Car() {
// No code inside, just allows object creation
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car(); // Default constructor is automatically called
System.out.println("Color: " + car1.color); // Output: Color: null
System.out.println("Year: " + car1.year); // Output: Year: 0
}
}
However, when a constructor is not defined, Java implicitly creates the default constructor for you.
This constructor does nothing except enable the creation of an object.
Color: null
Year: 0
The default constructor also initializes the instance variables of the class with their default values (e.g., 0
for numeric types, false
for booleans, and null
for objects).
You can also define your default constructor. It does not take any parameter and is used for initializing the instance variables with default values(if values not provided) and custom values.
class Car {
String color; // Instance variable
int year; // Instance variable
// Default constructor (explicitly defined)
Car() {
// You can initialize instance variables in the default constructor
color = "Red";
year = 2020;
}
void display() {
System.out.println("Color: " + color + ", Year: " + year);
}
}
public class Main {
public static void main(String[] args) {
// Creating a Car object, which invokes the default constructor
Car car1 = new Car();
car1.display(); // Output: Color: Red, Year: 2020
}
}
In this example, we define our default constructor explicitly, where we set the custom values for instance variables. And display() method is used to print the value.
Color: Red, Year: 2020
2. Parameterized Constructor:
When parameters are included in the parentheses of a constructor, it is called a parameterized constructor. A parameterized constructor allows you to initialize object instance variables with specific values at the time of object creation, rather than using default or hardcoded values.
In the previous example, where we explicitly define the default constructor and initialize instance variables (color
and year
) with fixed values (“Red” and 2020
), every object created will have the same values for these variables. This can be problematic if we need to create objects with different values for the fields.
To solve this issue, we can use a parameterized constructor. With a parameterized constructor, we can pass different values during object creation, and each object will have its own set of values.
class Car {
String color; // Instance variable
int year; // Instance variable
// Parameterized constructor
Car(String c, int y) {
color = c; // Assigning the passed parameter value to the instance variable
year = y; // Assigning the passed parameter value to the instance variable
}
// Method to display the values of the object
void display() {
System.out.println("Color: " + color + ", Year: " + year);
}
}
public class Main {
public static void main(String[] args) {
// Creating Car objects with different values for each
Car car1 = new Car("Red", 2020); // Pass data during object creation
Car car2 = new Car("Blue", 2021); // Pass different data during object creation
// Display the values of each object
car1.display(); // Output: Color: Red, Year: 2020
car2.display(); // Output: Color: Blue, Year: 2021
}
}
In this, we pass values to the constructor during object creation.
Color: Red, Year: 2020
Color: Blue, Year: 2021
If you Want to Learn about “What is Class and Object in Java?” then click here
Constructor Overloading in Java
Constructor overloading means defining multiple constructors within the same class, each with the same name (the class name) but with a different number of parameters, parameter data types, or both.
Java differentiates these constructors based on the number or type of parameters.
Constructor overloading is similar to method overloading.
By overloading constructors, we make the class more versatile. Constructor overloading provides flexibility for creating objects in different ways based on the data available or required for initialization.
Let’s understand the concept of constructor overloading with the help of an example.
Constructor Overloading in Java: Initializing Car Objects with Different Constructors
class Car {
String color;
int year;
String model;
// No-argument constructor
Car() {
color = "White";
year = 2020;
model = "Standard";
}
// Parameterized constructor with two arguments
Car(String c, int y) {
color = c;
year = y;
model = "Standard";
}
// Parameterized constructor with three arguments
Car(String c, int y, String m) {
color = c;
year = y;
model = m;
}
void display() {
System.out.println("Color: " + color + ", Year: " + year + ", Model: " + model);
}
}
public class Main {
public static void main(String[] args) {
// Using the no-argument constructor
Car car1 = new Car();
car1.display(); // Output: Color: White, Year: 2020, Model: Standard
// Using the constructor with two arguments
Car car2 = new Car("Red", 2021);
car2.display(); // Output: Color: Red, Year: 2021, Model: Standard
// Using the constructor with three arguments
Car car3 = new Car("Blue", 2022, "Sports");
car3.display(); // Output: Color: Blue, Year: 2022, Model: Sports
}
}
Explanation:
- No-Argument Constructor:
Car()
: This constructor does not take any arguments. It initializes the color
, year
, and model
instance variables with default values: "White"
, 2020
, and "Standard"
.
- Two-Parameter Constructor:
Car(String c, int y)
: This constructor takes two arguments (c
and y
) for color
and year
, while model
is set to "Standard"
.
- Three-Parameter Constructor:
Car(String c, int y, String m)
: This constructor takes three arguments, allowing initialization of all instance variables. The user can set color
, year
, and model
to their desired values.
In the main method, we make three objects, car1 uses a no-argument constructor, car2 uses a two-parameter constructor, and car3 uses a three-parameter constructor.
Color: White, Year: 2020, Model: Standard
Color: Red, Year: 2021, Model: Standard
Color: Blue, Year: 2022, Model: Sports
Constructor overloading enables multiple ways to initialize objects, allowing developers to create objects with different sets of data based on the constructor used.
What is Constructor Chaining in Java?
Constructor Chaining means calling one constructor from another within the same class. This concept is useful for avoiding duplicate code across constructors by reusing initialization code.
In Java, a constructor can call another constructor in the same class using the this()
keyword, optionally with parameters as needed.
Let’s understand constructor chaining with a program example.
Constructor Chaining in Java: Using Multiple Constructors in the Car Class
class Car {
String color;
int year;
String model;
Car(){
System.out.println("Default constructor called");
}
Car(String color) {
this();
this.color = color;
}
Car(String color,int year) {
this(color);
this.year = year;
}
Car(String color, int year, String model) {
this(color, year);
this.model = model;
}
void display() {
System.out.println("Color: " + color + ", Year: " + year + ", Model: " + model);
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Red", 2023, "SUV");
car1.display();
}
}
Explanation:
The program shows constructor chaining in Java, where constructors call each other to initialize a Car
object.
- Default constructor (
Car()
): Prints “Default constructor called”. - Single-parameter constructor (
Car(String color)
): Calls the default constructor to reuse code, then sets thecolor
. - Two-parameter constructor (
Car(String color, int year)
): Calls the single-parameter constructor, then sets theyear
. - Three-parameter constructor (
Car(String color, int year, String model)
): Calls the two-parameter constructor, then sets themodel
.
When Car car1 = new Car("Red", 2023, "SUV");
is called in main
, it triggers the chain of constructor calls, and display()
outputs:
Default constructor called
Color: Red, Year: 2023, Model: SUV
Copy Constructor in Java
A copy constructor in Java is used to create a new object as a copy of an existing object of the same class.
The copy constructor is helpful when working with complex objects where we want to operate on a copy of an object, rather than modifying the original directly.
Since Java doesn’t have a built-in copy constructor like some other languages, we can create our own by defining a constructor that takes an object of the same class as a parameter. This approach allows us to duplicate an object’s data into a new object.
Java Copy Constructor Example: Creating a Duplicate Object in the Car Class
class Car {
String color;
int year;
// Regular constructor
Car(String color, int year) {
this.color = color;
this.year = year;
}
// Copy constructor
Car(Car car) {
this.color = car.color;
this.year = car.year;
}
void display() {
System.out.println("Color: " + color + ", Year: " + year);
}
}
public class Main {
public static void main(String[] args) {
// Original object
Car car1 = new Car("Red", 2022);
car1.display();
// Copying car1 to car2 using the copy constructor
Car car2 = new Car(car1);
car2.display();
}
}
- Regular Constructor: The
Car(String color, int year)
constructor initializes thecolor
andyear
for a newCar
object. - Copy Constructor: The
Car(Car car)
constructor takes anotherCar
object as a parameter and copies its values into the new object.
When Car car2 = new Car(car1);
is called, it creates car2
as a copy of car1
. Running this code will print:
Color: Red, Year: 2022
Color: Red, Year: 2022
Conclusion
Constructors in Java are crucial for initializing objects. We’ve covered default and parameterized constructors, constructor overloading, constructor chaining, and the copy constructor. Each type offers flexibility in how objects are created and initialized, making the code cleaner and more efficient. Understanding these concepts helps in writing well-structured and maintainable Java programs.