Zach Cochran
by Zach Cochran
4 min read

Categories

Tags

Today we’re going to take a look at constructors in Java.

I’ve been slowly working my way through a bunch of intro level java courses over on pluralsight after a coworker had recommended the site to me a few weeks back. After jumping around between different lessons, I finally decided to land on the fundamentals course and stick there. Thankfully most of it has been review, but there’s been some stuff (like this), that’s been new info for me.

All of the code featured in this blog was either sourced from or influence by the sample code found in the Java Fundamentals course on pluralsight. You can find all of the sample code in my github repo here.

Constructors

Constructors weren’t a new topic for me. I was aware that every class needed to have one in order to compile, but there were a few things that I learned in this section that I didn’t know about.

Implied Constructor

While it’s true that every class must contain a constructor, that doesn’t mean that you must add one in yourself. In fact, at compile time, if no constructor is found, an empty constructor will be implied for you.

If you have a class called Biscuits, and you fill it with some values and your getters and setters, and implicit

public Biscuits() {

}

will be added in at compile time. It’s not something you’ll see in your code editor, but it will be there in the compiled code.

It’s important to note that as soon as you define one constructor, you must define all of them. So with the example above, if I were to define the following constructor:

public Biscuits(boolean tasty) {
   this.tasty = true;
}

then any code that was using the original implicit Biscuits() constructor will now fail. We would need to manually add it back in.

Multiple Constructors

When defining your classes, you’re actually able to define multiple constructors for the class. I guess this shouldn’t have been news for me, as I was already aware that you could do this same thing with methods, but I’d never seen it used in practice.

The general idea being that maybe you want to have the ability to initialize different values in different ways. Maybe sometimes you want to be able to set one value, maybe sometimes you want to set three.

For examples sake, let’s say we have a class called Passenger that looks like the following:

public class Passenger {
   private int freeBags;
   private int checkedBags;
   private double perBagFee;

   public Passenger() {
   }

   public Passenger(int freeBags) {
       setFreeBags(freeBags);
   }

   public Passenger(int freeBags, int checkedBags) {
       setFreeBags(freeBags);
       setCheckedBags(checkedBags);
   }

   public Passenger(double perBagFee) {
       setPerBagFee(perBagFee);
   }

   public int getFreeBags() {
       return freeBags;
   }

   private void setFreeBags(int freeBags) {
       this.freeBags = freeBags;
   }

   public int getCheckedBags() {
       return checkedBags;
   }

   private void setCheckedBags(int checkedBags) {
       this.checkedBags = checkedBags;
   }

   public double getPerBagFee() {
       return perBagFee;
   }

   private void setPerBagFee(double perBagFee) {
       this.perBagFee = perBagFee;
   }  
}

We can see that this data object has four different constructors available to it. And we can do this because we’re using unique identifiers. The way that we know they’re each unique is because of the number and type of parameters that each of the constructors accepts.

With those constructors created, we can then do the following initialization calls for Passengers:

public static void main(String[] args) {
   Passenger bob = new Passenger();
   Passenger jane = new Passenger(2);
   Passenger jill = new Passenger(2, 4);
   Passenger bill = new Passenger(50.0d);  
}

Chaining Constructors

The code above is fine, but there is a bunch of repeated code and things that we should probably clean up. Right now we’re enabling the user to set the price of their baggage fees, which could be a problem in the future.

We actually have the ability to call one constructor from another by using the this() method. This will basically call another constructor to be executed that matches the parameters that were passed in.

Now that we know this, let’s clean up the code from before:

public class Passenger {
   private int freeBags;
   private int checkedBags;
   private double perBagFee;

   public Passenger() {
   }

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

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

   private Passenger(double perBagFee) {
       setPerBagFee(perBagFee);
   }
   ...
}
  • We’ve moved our bag fee constructor to private so that it can no longer be called from the outside.
  • We’re using this to call the freeBags constructor from the freeBags, checkedBags constructor to reduce our code
  • We’re using this to set the perBagFee based on the number of free bags that the passenger gets

After doing this, we can no longer use our last initialization statement from before, as access to the double perBagFee constructor is no longer public:

public static void main(String[] args) {
   Passenger bob = new Passenger();
   Passenger jane = new Passenger(2);
   Passenger jill = new Passenger(2, 4);
//  Passenger bill = new Passenger(50.0d);
}

The thing to note here is that it MUST be the first call within the constructor. Putting it later will cause errors.

💚 A.B.L.