Working with object initialization and its customization

When you ask Java to create an instance of a specific class, something happens under the hood. Java creates a new instance of the specified type, the JVM (Java Virtual Machine) allocates the necessary memory, and then executes the code specified in the constructor.

When Java executes the code within the constructor, there is already a live instance of the class. Thus, the code in the constructor has access to the fields and methods defined in the class. Obviously, we must be careful in the code we put within the constructor because we might end up generating huge delays when we create instances of the class.

Tip

Constructors are extremely useful to execute setup code and properly initialize a new instance.

Let's forget about the hierarchy structure in which we were working for the classes that represent 2D shapes. Imagine that we have to code the Circle class as a standalone class that doesn't inherit from any other class. Before we can call either the calculateArea or calculatePerimeter methods, we want the radius field for each new Circle instance to have a value initialized to the appropriate value that represents the circle. We don't want new Circle instances to be created without specifying an appropriate value for the radius field.

Tip

Constructors are extremely useful when we want to define the values for the fields of the instances of a class right after their creation and before we can access the variables that reference the created instances. In fact, the only way to create instances of a specific class is to use the constructors we provide.

Whenever we need specific arguments to be available at the time we create an instance, we can declare many different constructors with the necessary arguments and use them to create instances of a class. Constructors allow us to make sure that there is no way of creating specific classes without using the provided constructors that make the necessary arguments required. Thus, if the provided constructor requires a radius argument, we won't be able to create an instance of the class without specifying a value for the radius argument.

Imagine that we have to code the Rectangle class as a standalone class that doesn't inherit from any other class. Before we can call either the calculateArea or calculatePerimeter methods, we want both the width and height fields for each new Rectangle instance to have their values initialized to the appropriate values that represent each rectangle. We don't want new Rectangle instances to be created without specifying an appropriate value for the width and height fields. Thus, we will declare a constructor for this class that requires values for width and height.