Search code examples
javaconstructordefault-constructor

The relationship between a no-arg constructor and a constructor with arguments


Please have a look at the following class:

public class Loan {

    private double annualInterestRate;
    private int numberOfYears;
    private double loanAmount;
    private java.util.Date loanDate;

    // Default constructor
    public Loan() {
        this(2.5, 1, 1000);
    }

}

For the codeline this(2.5, 1, 1000); , I get the following error message in Eclipse: "The constructor Loan(double, int, int) is undefined". This error disappears when adding a new constructor with arguments:

// Construct a loan with specified annual interest rate, number of years and loan amount
    public Loan(double annualInterestRate, int numberOfYears, int loanAmount) {
        this.annualInterestRate = annualInterestRate;
        this.numberOfYears = numberOfYears;
        this.loanAmount = loanAmount;
        loanDate = new java.util.Date();
    }

Why does the creation of the constructor with arguments remove the "undefined" error from the default constructor? How are these two different constructors related to each other?

How do I know that the values in this(2.5, 1, 1000) are assigned to the right data fields? I assume 2.5 should be assigned to annualInterestRate, 1 to numberOfYears, and 1000 to loanAmount.


Solution

  • In your no-arg constructor, the line

            this(2.5, 1, 1000);
    

    explicitly means "call another constructor for the same class as the current constructor, but which takes these arguments".

    So that's why adding the other constructor fixes the problem. The order in which you pass the arguments needs to match the order in which the parameters appear on that constructor, that constructor's parameter list defines the order you need to put the arguments in when calling it.

    The relationship between these two constructors is that they are chained. The one with the 3 arguments is the primary constructor, the other calls the primary constructor with default values. Designing constructors in this way helps to initialize your objects consistently, because a single primary constructor always gets called. (For instance, the loanDate instance field gets set regardless of which constructor you call.)