Search code examples
javaparametersconstructorvisibilitychaining

Constructor Chaining and Visibility in Java


Consider this class:

public class Passenger {
  public Passenger() {

  }

  public Passenger(int freeBags) {
      this(freeBags > 1 ? 25.0d : 50.0d);
      this.freeBags = freeBags;
  }

  public Passenger(int freeBags, int checkedBags) {
      this(freeBags);
      this.checkedBags = checkedBags;
  }

  private Passenger(double perBagFee) {
      this.perBagFee = this.perBagFee;
  }
}


Passenger fred = new Passenger(2);

If I understand correctly, 'fred' is a new instance of Passenger. 'fred' calls the constructor with one parameter which is public Passgener(int freeBags). Then this line this(freeBags > 1 ? 25.0d : 50.0d) gets called. Here is my question: How does the compiler know that the conditional statement in the first constructor to chain to the 'private' constructor? My guess would be that the 'd' in the conditional statement points to the double parameter in the private constructor. But what if there was another constructor with a double parameter? What would it chain to then? There is no mention of perBagFee in the first constructor. I'm a little confused.


Solution

  • EDIT

    How does the compiler know that the conditional statement in the first constructor to chain to the 'private' constructor?

    Since either values returned by your ternary expression are double values, the compiler knows that this call refers to your constructor method that received one double argument.

    My guess would be that the 'd' in the conditional statement points to the double parameter in the private constructor.

    The .0d suffix merely says that those are double values.

    There is no mention of perBagFee in the first constructor

    Method arguments names have no relevance whatsoever outside the method itself. The compiler will always check for what kind of object does your expression evaluate to in order to figure out which method you want to call.

    But what if there was another constructor with a double parameter?

    Try it :) Inside the same class, you cannot define two methods (constructor or not) with the same signature, regardless of the visibility. Official docs on methods overloading:

    Overloaded methods are differentiated by the number and the type of the arguments passed into the method.

    You cannot declare more than one method with the same name and the same number and type of arguments, because the compiler cannot tell them apart.