JAVA Tutorials

What are Constructors and Overloading

Constructor

is a special method that has no return type and matches the name of the class. They are using for the creation of new objects. For example: 

public class Fish {
public Fish() {
System.out.println(“constructor”);
}
} 

The creation of new object is called instantiation, because it creates a new instance of the class. To call constructor we need to write keyword new followed by the name of the class we want to instantiate: new Fish().

There are three types of constructors in the Java language:

  • default constructors;
  • constructors without arguments;
  • parameterized constructors.

Default constructors.

Every class in Java has a constructor. If you don’t create any constructors in the class, Java will add one for you without any parameters. It is called the default constructor. Let’s create a class without any constructor:

public class Dog {  

 

Java compiler will generate the constructor for us:

public Dog() {}

This will happen during compilation. If you check at the file Dog.java, the constructor will still be missing. It is only in the compiled file Dog.class that it makes an appearance. It is important to remember that a default constructor is only supplied if there are no constructors present. It does not have any arguments. Most of the time it is fine to have just default constructor because other fields can be accessed and initialized through getters and setters methods.

 

Constructors without arguments. Sometimes the default constructor is not enough. In this case, we can create a constructor with the same signature as default, but with a body. It will be some kind of overriding the default method. We don’t pass any argument to this constructor to initialize class fields, but we can do some logging, checking network connection, checking resources, etc. Let’s look at the example:

public class Monkey {
          public Monkey() {
              System.out.println(“Object of the class Monkey is created”);
}
public static void main (String[] args) {
             Monkey myMonkey = new Monkey();
       }
}

Parameterized constructors. Constructors are typically used to initialize instance variables. For example:

public class Fish { 

private int weight; 

private int length;

public Fish(int weight, int length) { 

this.weight = weight; 

this.length =  length;

}

public printInfo() {

        System.out.println(“The fish weight is ” + weight + “ and length is ” + length);

}

public static void main (String[] args) {

        // creation of our objects with specific field values

        Fish myFish1 = new Fish (290, 30);

        Fish myFish2 = new Fish (120, 17);

        //calling methods to display values of our objects

        myFish1.printInfo();

        myFish2.printInfo();

}

}

Here we assign the parameters weight and length to the instance variable weight and length. Keyword this tells Java that you want to reference an instance variable. In the method main we are creating two objects of the class Fish with a different value of fields weight and length. The output of the current code will be:

The fish weight is 290 and length is 30
The fish weight is 120 and length is 17

Overloading of constructors in Java

In Java, we can overload all methods, including constructors. Your class can have multiple constructors in the same class, but with a different signature. The name of constructors is always the same since it has to be the same as the name of the class. So constructors must have different parameters in the list and their types in order to be overloaded.

public class Mouse() {

    private int weight; 

    private String color; 

    public Mouse(int weight) {

        this.weight = weight;

    }

    public Mouse(int weight, String color) {

        this.weight = weight;

        this.color = color;

    }

    public static void main (String[] args) {

         Mouse myMouse = new Mouse(350);

        Mouse myGrayMouse = new Mouse(350, “gray);

    }

}

Overloaded constructors can call each other. This approach is called constructor chaining. For example:

public class Mouse() {

    private int weight; 

    private String color; 

    private String name;

    public Mouse(int weight) {

        this.weight = weight;

        System.out.println(“We are in the constructor with signature Mouse(int weight).”);

    }

    public Mouse(int weight, String color) {

        this(weight);

        this.color = color;

        this.name = name;

        System.out.println(“We are in the constructor with signature Mouse(int weight, String color).”);

    }

    public Mouse(int weight, String color, String name) {

        this(weight, color);

        this.name = name;

        System.out.println(“We are in the constructor with signature Mouse(int weight, String color, String name).”);

    }

    public static void main (String[] args) {

         Mouse myMouse = new Mouse(350, “gray”, “Mickey”);

    }

}

The output of the current application will be:

We are in the constructor with signature Mouse(int weight).
We are in the constructor with signature Mouse(int weight, String color).
We are in the constructor with signature Mouse(int weight, String color, String name).

The third constructor will call the second constructor, then the second constructor will call the first constructor. The fist constructor will finish its work and, just after this, the message will be printed. After we will move to the second constructor, then to the third.

We can call the constructor of a class from its superclass:

public class Animal {

        public Animal() {

            System.out.println(“In the superclass.”);

        }

    }

    public class Lion extends  Animal {

        public  Lion() {

            super();

            System.out.println(“In the subclass.”);

        }

    }

    public class TestLion {

        public static void main(String[] args) {

            Lion lion = new Lion();

        }

    }

The output og this small application will be:

In the superclass.
In the subclass.

Let’s look at the wrong example of overloading our constructor:

public Mouse(int weight) {}
public Mouse(int length) {} // DOES NOT COMPILE

Changing the parameter name is not enough. It has to be a parameter with a different type.
Also, there is a tricky situation with varargs. This code does not compile:

public Mouse(int[] parameters) {}
public Mouse(int… parameters) {} // DOES NOT COMPILE

The method doesn’t look the same, but it compiles to the same parameter list. SO, we cannot do overloading like this.

 Here is one more interesting example of the overloading:

public Mouse(int weight) {}
public Mouse(short weight) {} //Will compile

If we call the new Mouse(50) the constructor Mouse(int weight) will be called. To call constructor Mouse(short weight) you have to write new Mouse((short)50);

A similar situation will be with this overloading:

public Mouse(int weight) {}
public Mouse(long weight) {} //Will compile

To call the constructor with a parameter that has the long type you need to write:

new Mouse(50L);

Here is another example:

public Mouse(int weight) {}
public Mouse(Integer length) {}//Will compile

In this case, code will compile. The situation will be the same as in the previous example. In the case of calling the new Mouse(50), the constructor Mouse(int weight) will be called. The autoboxing will have a place if the primitive int version isn’t present. There is no reason for Java to do the extra work when the primitive int version is provided. 

In Java language, a constructor cannot be with modifiers abstract, static, final, and synchronized, but can be with all kinds of access modifiers. Interesting that class can have several constructors and each can have its own access modifier. Usually, constructors are declared with modifier public.  If a constructor is protected then it can be only accessed by classes in the same package or subclasses of that class. 

Private constructors are widely used when you need to have just one instance of your class. It is called Singleton.  In this case, you need to create a static method that will return your object, because the constructor is private and you cannot call it from another class. Usually, as the name of that static method is used getInstance(). Here is an example:

public class Zoo {

        //variable for single instance of  our class Zoo

        private static Zoo zoo;

        

        //private constructor 

        private Zoo() {

             System.out.println(“One instance of Zoo is created”);

        }

        // method to get instance of our Zoo

        public static Zoo getInstance() {

            if(zoo == null) {

                zoo = new Zoo();

            }

            return zoo;

        }    

    }  

    public class TestSingleton {

        public static void main (String[] args) {

            Zoo zoo1 = Zoo.getInstance();

            Zoo zoo2 = Zoo.getInstance();

            Zoo zoo3 = Zoo.getInstance();

        }

    }

As you see, we will create a new instance of class Zoo just in case we don’t have one already created. The output of current code will be “One instance of Zoo is created”. And it will be printed just one time.

Throwing Exceptions From a Constructor. 

We can throw exceptions from a constructor and it is legal. Here is an example:

public class Rabbit throws Exception {

        public Rabbit(String name) {

            if (name == null) {

                new Exception (“The name parameter cannot be null!”)

            }

        }

    }

 

An Exception is a part of a constructor’s declaration. Let’s look at the example of calling constructor:

    public class TestRabbit {

        public static void main (String[] args) {

            Rabbit rabbit = null;

            String name = “Bunny”;

            try {

                rabbit = new Rabbit(name);

            } catch(Exception exception) {

                //handle exception 

            }

        }

    }

 

If a variable name is null, not the “Bunny”, the exception will be thrown from the constructor, and an instance of class Rabbit will not be created, and the variable rabbit will remain null. The throwing of exceptions prevents the creation of an invalid object.

Facebook Comments
Tags

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to top button
Close
Close