Java Constructor Tutorial

Avatar

By squashlabs, Last Updated: July 21, 2023

Java Constructor Tutorial

Introduction to Constructors

Constructors are special methods in Java that are used to initialize objects of a class. They are called automatically when an object is created and are responsible for setting initial values for the object’s attributes. Constructors have the same name as the class they belong to and do not have a return type.

Related Article: How To Parse JSON In Java

Defining Constructors: Syntax and Structure

Constructors are defined using the following syntax:

public class ClassName {
    // Constructor
    public ClassName() {
        // constructor body
    }
}

Here’s an example of a simple constructor:

public class Person {
    private String name;
    
    // Constructor
    public Person() {
        name = "John Doe";
    }
}

In this example, the constructor initializes the name attribute of the Person class with the value “John Doe”.

Constructor Overloading: Concept and Usage

Constructor overloading is the process of defining multiple constructors for a class with different parameters. Each constructor can have a unique set of parameters, allowing objects to be initialized in different ways.

Here’s an example of constructor overloading:

public class Rectangle {
    private int length;
    private int width;
    
    // Constructor with no parameters
    public Rectangle() {
        length = 0;
        width = 0;
    }
    
    // Constructor with length and width parameters
    public Rectangle(int l, int w) {
        length = l;
        width = w;
    }
}

In this example, the Rectangle class has two constructors. The first constructor initializes the length and width attributes to 0, while the second constructor allows the length and width to be specified during object creation.

Default Constructor: Explanation and Usage

A default constructor is a constructor that takes no parameters. If a class does not have any constructors defined, Java automatically provides a default constructor. The default constructor initializes all attributes of the class to their default values.

Here’s an example of a default constructor:

public class Car {
    private String make;
    private String model;
    
    // Default constructor
    public Car() {
        make = "Unknown";
        model = "Unknown";
    }
}

In this example, the Car class has a default constructor that initializes the make and model attributes to “Unknown”.

Related Article: How To Convert Array To List In Java

Parameterized Constructor: Explanation and Usage

A parameterized constructor is a constructor that takes one or more parameters. It allows objects to be initialized with specific values provided during object creation.

Here’s an example of a parameterized constructor:

public class Employee {
    private String name;
    private int age;
    
    // Parameterized constructor
    public Employee(String n, int a) {
        name = n;
        age = a;
    }
}

In this example, the Employee class has a parameterized constructor that initializes the name and age attributes with the values provided during object creation.

Use Case 1: Utilizing Constructors in Object Creation

Constructors are commonly used during object creation to initialize object attributes with specific values. Let’s consider an example where we create objects of a Person class with different names:

public class Person {
    private String name;
    
    // Constructor
    public Person(String n) {
        name = n;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("Alice");
        Person person2 = new Person("Bob");
        
        System.out.println(person1.getName()); // Output: Alice
        System.out.println(person2.getName()); // Output: Bob
    }
}

In this example, the Person class has a constructor that takes a name parameter. During object creation, we provide different names for each object, resulting in different values for the name attribute.

Use Case 2: Exploiting Constructors for Instantiating Arrays

Constructors can also be used to initialize arrays of objects. When an array is created, a constructor is called for each element in the array, allowing each element to be initialized individually.

Let’s consider an example where we create an array of Rectangle objects and initialize each object with different lengths and widths:

public class Rectangle {
    private int length;
    private int width;
    
    // Constructor
    public Rectangle(int l, int w) {
        length = l;
        width = w;
    }
}

public class Main {
    public static void main(String[] args) {
        Rectangle[] rectangles = new Rectangle[3];
        rectangles[0] = new Rectangle(2, 4);
        rectangles[1] = new Rectangle(3, 5);
        rectangles[2] = new Rectangle(4, 6);
        
        System.out.println(rectangles[0].getArea()); // Output: 8
        System.out.println(rectangles[1].getArea()); // Output: 15
        System.out.println(rectangles[2].getArea()); // Output: 24
    }
}

In this example, we create an array of Rectangle objects and initialize each object with different lengths and widths. This allows us to store and manipulate multiple Rectangle objects in an array.

Related Article: How To Iterate Over Entries In A Java Map

Use Case 3: Employing Constructors in Singleton Pattern

Constructors are commonly used in the singleton pattern, which ensures that only one instance of a class is created throughout the application.

Here’s an example of implementing the singleton pattern using a constructor:

public class Singleton {
    private static Singleton instance;
    
    // Private constructor
    private Singleton() {
        // Initialization code
    }
    
    // Static method to get the singleton instance
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

In this example, the Singleton class has a private constructor, preventing direct instantiation. The getInstance() method is used to retrieve the singleton instance, creating it if necessary.

Best Practice 1: Avoiding Excessive Constructor Overloading

While constructor overloading can be useful, it is important to avoid excessive overloading to keep the codebase maintainable. Having too many constructors with different sets of parameters can make the code confusing and difficult to understand.

Instead, consider using setters and getters to modify and retrieve object attributes after object creation.

Best Practice 2: Favoring Parameterized Constructors over Default

In general, it is recommended to use parameterized constructors over default constructors. Parameterized constructors allow for more flexibility in object initialization and make the code more explicit.

Using parameterized constructors also helps enforce the principle of encapsulation by ensuring that required attributes are provided during object creation.

Related Article: How To Split A String In Java

Real World Example 1: Constructors in Java Library Classes

Java library classes extensively use constructors to initialize their objects with the desired initial state. For example, the ArrayList class provides multiple constructors to create an array list object with different initial capacities.

Here’s an example of using the ArrayList constructor:

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        
        System.out.println(fruits); // Output: [Apple, Banana, Orange]
    }
}

In this example, we create an ArrayList object and add multiple elements to it. The ArrayList constructor is called implicitly during object creation.

Real World Example 2: Constructors in Enterprise Applications

Constructors play a vital role in enterprise applications where complex objects need to be initialized with specific dependencies and configurations. For example, in a web application, a controller class may have a constructor that takes service classes as dependencies.

Here’s an example of using constructors in an enterprise application:

public class UserController {
    private UserService userService;
    private EmailService emailService;
    
    // Constructor with dependencies
    public UserController(UserService userService, EmailService emailService) {
        this.userService = userService;
        this.emailService = emailService;
    }
    
    // Other methods
}

In this example, the UserController class has a constructor that takes UserService and EmailService objects as dependencies. This allows the controller to be created with the required dependencies, ensuring proper functionality.

Performance Consideration 1: Impact of Constructors on Object Creation

Constructors are called during object creation and can have an impact on performance, especially if they perform complex operations or require significant resources. It is important to consider the performance implications of constructors, especially in resource-intensive applications.

It is recommended to keep constructors lightweight and avoid unnecessary computations or expensive operations.

Related Article: How To Convert Java Objects To JSON With Jackson

Performance Consideration 2: Constructor Overloading and Performance

Constructor overloading can have an impact on performance if multiple constructors are defined with complex parameter types or if the number of constructors becomes excessive. Each additional constructor adds complexity and overhead during object creation.

To optimize performance, consider using a limited number of constructors with well-defined parameter sets and minimal overhead.

Advanced Technique 1: Constructors and Inheritance

Constructors are also inherited by subclasses. When a subclass is created, the constructor of the superclass is called implicitly before the subclass constructor. This ensures that the superclass’s attributes and behavior are properly initialized.

Here’s an example illustrating constructor inheritance:

class Animal {
    protected String name;
    
    public Animal(String n) {
        name = n;
    }
}

class Dog extends Animal {
    private String breed;
    
    public Dog(String n, String b) {
        super(n); // Call to superclass constructor
        breed = b;
    }
}

In this example, the Dog class extends the Animal class. The Dog class has its own constructor that initializes the breed attribute, but it also calls the superclass constructor to initialize the name attribute.

Advanced Technique 2: Constructors and Polymorphism

Constructors can be used in combination with polymorphism to create objects of different subclasses using a superclass constructor. This allows for flexibility and code reusability.

Here’s an example demonstrating constructors and polymorphism:

abstract class Shape {
    protected int sides;
    
    public Shape(int s) {
        sides = s;
    }
    
    public abstract void draw();
}

class Rectangle extends Shape {
    public Rectangle() {
        super(4); // Call to superclass constructor
    }
    
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

class Circle extends Shape {
    public Circle() {
        super(0); // Call to superclass constructor
    }
    
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape1 = new Rectangle();
        Shape shape2 = new Circle();
        
        shape1.draw(); // Output: Drawing a rectangle
        shape2.draw(); // Output: Drawing a circle
    }
}

In this example, the Shape class is an abstract class with a constructor and an abstract draw() method. The Rectangle and Circle classes extend the Shape class and provide their own implementations of the draw() method.

The superclass constructor is called implicitly when creating objects of the subclasses, and polymorphism allows the draw() method to be invoked based on the actual object type.

Related Article: Storing Contact Information in Java Data Structures

Code Snippet 1: Defining a Simple Constructor

public class Person {
    private String name;
    
    // Constructor
    public Person(String n) {
        name = n;
    }
}

In this code snippet, the Person class has a constructor that takes a name parameter. The constructor initializes the name attribute with the value provided during object creation.

Code Snippet 2: Overloading Constructors

public class Rectangle {
    private int length;
    private int width;
    
    // Constructor with no parameters
    public Rectangle() {
        length = 0;
        width = 0;
    }
    
    // Constructor with length and width parameters
    public Rectangle(int l, int w) {
        length = l;
        width = w;
    }
}

In this code snippet, the Rectangle class has two constructors. The first constructor initializes the length and width attributes to 0, while the second constructor allows the length and width to be specified during object creation.

Code Snippet 3: Parameterized Constructor in action

public class Employee {
    private String name;
    private int age;
    
    // Parameterized constructor
    public Employee(String n, int a) {
        name = n;
        age = a;
    }
}

In this code snippet, the Employee class has a parameterized constructor that initializes the name and age attributes with the values provided during object creation.

Related Article: How to Convert JSON String to Java Object

Code Snippet 4: Singleton Pattern via Constructor

public class Singleton {
    private static Singleton instance;
    
    // Private constructor
    private Singleton() {
        // Initialization code
    }
    
    // Static method to get the singleton instance
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

In this code snippet, the Singleton class has a private constructor, preventing direct instantiation. The getInstance() method is used to retrieve the singleton instance, creating it if necessary.

Code Snippet 5: Constructors in Inherited Classes

class Animal {
    protected String name;
    
    public Animal(String n) {
        name = n;
    }
}

class Dog extends Animal {
    private String breed;
    
    public Dog(String n, String b) {
        super(n); // Call to superclass constructor
        breed = b;
    }
}

In this code snippet, the Dog class extends the Animal class. The Dog class has its own constructor that initializes the breed attribute, but it also calls the superclass constructor to initialize the name attribute.

Error Handling: Managing Constructor Exceptions

Constructors can throw exceptions if necessary. It is important to handle these exceptions appropriately to ensure proper error handling and recovery.

Here’s an example of handling exceptions in a constructor:

public class Person {
    private String name;
    
    // Constructor
    public Person(String n) {
        if (n == null) {
            throw new IllegalArgumentException("Name cannot be null");
        }
        name = n;
    }
}

In this example, the Person class constructor throws an IllegalArgumentException if the name parameter is null. This ensures that the object cannot be created with an invalid state.

It is important to document and communicate the exceptions that constructors can throw to users of the class.

How to Reverse a String in Java

This article serves as a guide on reversing a string in Java programming language. It explores two main approaches: using a StringBuilder and using a char array.... read more

How to Generate Random Integers in a Range in Java

Generating random integers within a specific range in Java is made easy with the Random class. This article explores the usage of java.util.Random and ThreadLocalRandom... read more

How to Retrieve Current Date and Time in Java

Obtain the current date and time in Java using various approaches. Learn how to use the java.util.Date class and the java.time.LocalDateTime class to retrieve the... read more

Java Equals Hashcode Tutorial

Learn how to implement equals and hashcode methods in Java. This tutorial covers the basics of hashcode, constructing the equals method, practical use cases, best... read more

How To Convert String To Int In Java

How to convert a string to an int in Java? This article provides clear instructions using two approaches: Integer.parseInt() and Integer.valueOf(). Learn the process and... read more

Java Composition Tutorial

This tutorial: Learn how to use composition in Java with an example. This tutorial covers the basics of composition, its advantages over inheritance, and best practices... read more