Constructors In Java

From Wikipedia, the free encyclopedia

In class-basedobject-oriented programming, a constructor (abbreviation: ctor) is a special type of subroutine called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.

Let us go over the topics we’ve covered so far. Java is an “Object Oriented Programming” language. Everything we do in Java we do use objects. You are in charge of an object’s lifecycle. If you’re going to write Java, you’re going to have to create objects. You’ll get there sooner or later. You decide when and how to create it. You decide when it should be destroyed. Except that you don’t actually destroy the object; instead, you abandon it. However, once abandoned, the Garbage Collector (gc) can remove it, reclaiming the memory that the object was once a part of. Some of them must be let go, or RAM will run out.

The Stack and the Heap: WHERE THINGS LIVE

We are interested in two types of memory in Java: the Stack and the Heap.

Instance variables are variables that have been declared inside a class but outside any method. They are declared within a class but not within any method.
Local variables are variables declared within a method parameter or method body.

All local variables are stored on the stack, in the frame associated with the method where the variables have been declared.

image 14 - Constructors In Java

Object reference variables function in the same way that primitive variables do. If the reference is declared as a local variable it is stored on the stack.

Regardless of type, all objects reside in the heap. It does not matter whether the reference is local or instance variable.

image 15 - Constructors In Java

We have discussed these in our previous tutorial.

How To Create An Object In Java?

We can now enter the mysterious world of object creation now that you know where variables and objects live. Remember the three steps of object declaration and assignment:

STEP ONE: CREATE AN OBJECT
STEP TWO: DECLARE A REFERENCE VARIABLE
STEP THREE: ASSIGN THE OBJECT TO THE REFERENCE

However, step one—where a miracle occurs and the new object is “born”—has remained a Big Mystery until now. Get ready to learn about the facts of object life. I hope you’re not scared.

image 16 - Constructors In Java

When people first starts learning Java they are often get confused while seeing the following statement:

Mobile myMobile = new Mobile();

The beginner programmers often ask the question – Are we calling a method named Mobile()? The confusion is justified as it sure looks like it. But the answer to this question is a BIG “NO”!

LZABtGN69Sne7lmbvxJBJWgjfS5dFR KOU VUcjyU5BQadCDKH0buvAkxCKU Q1JM90X 90DLViSNmc YSpEaW7Bq5sJubv5Ml3mmssHvNikUyGcAq926M780j5hKDkuDpev6z 26fmHd0n VoU 9BjsqL480bFGxLTC9LSdh3hk S917f I6M0tjA - Constructors In Java

We are calling the Mobile constructor. A constructor has the appearance and feel of a method, but it is not one. It contains the code that is executed when you say new. In other words, the code that is executed when an object is instantiated.

The keyword new followed by the class name is the only way to call a constructor. The JVM locates that class and invokes its constructor. (OK, so this isn’t the only way to call a constructor. However, it is the only way to do it from the outside of a constructor. With some restrictions, you can call a constructor from within another constructor, but we’ll get into that later in the tutorial).

But where is the constructor? If we didn’t write it, who did?

You can write a constructor for your class (which we're about to do), but if you don't, the compiler will!

Here’s what the compiler’s default constructor looks like:

public Mobile(){

}

Look carefully at the above code snippet and try to figure out what is missing. This is different from a method as there is no return type in this code snippet. If this were a method you would have to declare a return type between “public” and “Mobile”.

The second difference is – it’s name is the same as the class name. That’s mandatory.

How To Construct A Mobile?

A constructor is characterized by the fact that it executes before the object can be assigned to a reference.

That means you get to step in and do things to prepare the object for use. In other words, before anyone can use the remote control for an object, the object has the opportunity to assist in its own construction. We’re not doing anything useful in our Mobile constructor, but it still demonstrates the sequence of events.

//program 1
public class Mobile{
    public Mobile(){
        System.out.println("Beep Beep!");
    }
}

public class MobileTest{
    public static void main(String[] args){
        Mobile myMobile = new Mobile();
    }
}

How To Initialize The State Of A New Mobile?

Constructors are commonly used to initialize the state of an object. To put it another way, to create and assign values to the object’s instance variables.

public Mobile(){
screenSize = 6.5;
}

It is okay when the developers beforehand knows how big the screen size of a Mobile object should be. But what if we want the programmer who is using Mobile to determine the screen size of a specific Mobile?

Assume the Mobile has a screenSize instance variable, and you want the programmer to set the screenSize of the new Mobile using your Mobile class. How could you manage it?

You could, however, add a setScreenSize() setter method to the class. However, this causes the Mobile to be temporarily without a screenSize, requiring the Mobile user to write two statements: one to create the Mobile and one to call the setScreenSize() method. To set the initial screenSize of the Mobile, the code below employs a setter method.

//MobileTest.java
class Mobile{
    double screenSize;

    public Mobile() {
        System.out.println("Beep Beep!");  
    }

    public void setScreenSize(Double newScreenSize) {
        screenSize = newScreenSize;
    }
   
}

public class MobileTest{
    public static void main(String[] args) {
       
        Mobile aMobile = new Mobile();


        aMobile.setScreenSize(6.5);
    }
}

This approach is a bad programming approach. When we say – Mobile aMobile = new Mobile(); a new mobile object is already in existence after the execution of this line, but without a screen size. And then you are relying on the Mobile-user to KNOW that Mobile creation is a two-part process: one to call the constructor and one to call the setter.

If an object should not be used until one or more of its state variables (instance variables) have been initialized, don’t let anyone touch a Mobile object until you’re finished initializing!

Allowing someone to create—and obtain a reference to—a new Mobile object that isn’t quite ready for use until that person calls the setScreenSize() method is usually far too risky. How will the Mobile-user know that he needs to call the setter method after creating a new Mobile?

The constructor is the best place to put initialization code. You only need to create a constructor with arguments.

class Mobile{
    double screenSize;

    public Mobile(double newScreenSize) {
        System.out.println("Beep Beep!");  
        screenSize = newScreenSize;
        System.out.println("Mobile Screen Size : " + screenSize + " inch!");
    }
}

public class MobileTest{
    public static void main(String[] args) {
        Mobile aMobile = new Mobile(6.5);
    }
}

Q: Why do you need to write a constructor if the compiler writes one for you?

If you require code to help initialize and prepare your object for use, you must write your own constructor. You might, for example, be reliant on user input before you can finish preparing the object. Another reason you might need to write a constructor, even if you don’t need any constructor code yourself. It has to do with your superclass constructor, which we’ll go over in a moment.

Q: How can you tell a constructor from a method? Can you also have a method that’s the same name as the class?

Java allows you to declare a method that has the same name as your class. But that doesn’t make it a constructor. The return type is what distinguishes a method from a constructor. A return type is required for methods, but constructors cannot have a return type.

Q: Are constructors inherited? If you don’t provide a constructor but your superclass does, do you get the superclass constructor instead of the default?

Nope. Constructors are not inherited. We’ll look at that in just a few pages.

What If The Mobile Constructor Accepts An Argument?

Consider this. There is only one Mobile constructor in the previous example,  and it accepts a double argument to specify the screenSize of the Mobile. That may not be a major issue, but it does complicate matters. It is more difficult for a programmer to create a new Mobile object, especially If the programmer is unsure of the screenSize of a Mobile. Wouldn’t it be nice to have a standard size for a Mobile screen so that even if the user is unsure of the appropriate screenSize, he can still create a functional Mobile?

Assume you want Mobile users to have TWO options for creating a Mobile: one in which they supply the Mobile screenSize (as the constructor argument) and one in which they don’t specify a screenSize and thus get your default Mobile screenSize.

This cannot be accomplished with a single constructor.

Remember that if a method (or constructor—same rules) has a parameter, you must pass that parameter type argument when invoking that method or constructor. You can’t just say, “If no arguments are passed to the constructor, use the default screenSize,” because they won’t be able to compile without a double argument to the constructor call. You could try something like this:

class Mobile{
    double screenSize;

    public Mobile(double newScreenSize) {
        //If the parameter value is zero, the new Mobile will have a default screenSize;
        //otherwise, the parameter value will be used for the screenSize. This is NOT a good solution.
        if (newScreenSize == 0) {
            screenSize = 5.0;
        }else{
            screenSize = newScreenSize;
        }
        System.out.println("Beep Beep!");  
        screenSize = newScreenSize;
        System.out.println("Mobile Screen Size : " + screenSize + " inch!");
    }
}

public class MobileTest{
    public static void main(String[] args) {
        Mobile aMobile = new Mobile(6.5);
    }
}

However, the programmer creating a new Mobile object must understand that passing a “0” is the protocol for obtaining the default Mobile screenSize. It’s pretty dreadful. What if the other programmer is unaware of this? What if he truly desires a zero-screenSize Mobile?

(Assuming a Mobile of zero screenSize is permitted.) If you don’t want zero-screenSized Mobile objects, include validation code in the constructor.) The point is that distinguishing between a genuine “I want zero for the screenSize” constructor argument and a “I’m sending zero so you’ll give me the default screenSize, whatever that is” constructor argument may not always be possible.

A proper way to do this is given below:

class Mobile{
    double screenSize;

    public Mobile() {
        //default mobile screen size
        screenSize = 5.0;
        System.out.println("Mobile Screen Size : " + screenSize + " inch!");

    }

    public Mobile(double newScreenSize) {
        System.out.println("Beep Beep!");  
        //use newScreenSize parameter
        screenSize = newScreenSize;
        System.out.println("Mobile Screen Size : " + screenSize + " inch!");
    }
}

public class MobileTest{
    public static void main(String[] args) {
        Mobile aMobile = new Mobile(6.5);
        Mobile anotherMobile = new Mobile();

    }
}

So this “two-options-to-make-a-Mobile” idea needs two constructors. One that takes a double and one that doesn’t. If you have more than one constructor in a class, it means you have overloaded constructors.

Isn’t it true that the compiler always generates a no-arg constructor for you?

You might believe that if you only write a constructor with arguments, the compiler will notice that you don’t have a no-arg constructor and insert one for you. But that is not the case. Only if you say nothing about constructors does the compiler get involved in constructor-making.

If you write a constructor that accepts arguments and wants a no-arg constructor, you must write the no-arg constructor yourself! As soon as you provide a constructor, ANY kind of constructor, the compiler backs off and says, “OK Buddy, looks like you’re in charge of constructors now.”

If a class has more than one constructor, the constructors MUST have different argument lists.

The order and types of arguments are included in the argument list. You can have multiple constructors as long as they are distinct. This is also possible with methods, but we’ll cover that in a later tutorial.

Overloaded constructors indicate that your class contains more than one constructor.

Each constructor must have a unique argument list in order to compile!

The class below is legal because each of the five constructors has a unique argument list. The class would not compile if you had two constructors that only took ints. It makes no difference what you call the parameter variable. The variable type (int, Dog, etc.) and order are important. You can have two constructors with the same type as long as the order is different. A constructor that accepts a String and then an int is not the same as one that accepts an int and then a String.

public class Mushroom {
    public Mushroom(int size) { }
    public Mushroom( ) { }
    public Mushroom(boolean isMagic) { }
    public Mushroom(boolean isMagic, int size) { }
    public Mushroom(int size, boolean isMagic) { }
}

KEY FACTS

  • Instance variables are stored on the Heap within the object to which they belong.
  • If the instance variable is a reference to an object, the reference and the object to which it refers are both on the Heap.
  • A constructor is a code that is executed when you use the keyword new on a class type.
  • A constructor must have the same name as the class and cannot return anything.
  • A constructor can be used to initialize the state (i.e. the instance variables) of the object being built.
  • If you don’t include a constructor in your class, the compiler will include one.
  • A no-arg constructor is always used as the default constructor.
  • If you include a constructor in your class, the compiler will not create the default constructor.
  • If you want a no-arg constructor and you already have a constructor with arguments, you’ll have to build it yourself.
  • If possible, provide a no-arg constructor to make it easier for programmers to create a working object. Provide default values.
  • Overloaded constructors indicate that your class contains more than one constructor.
  • Different argument lists are required for overloaded constructors.
  • It is not possible to have two constructors with the same argument lists. The order and/or type of arguments is included in an argument list.
  • Even if you don’t explicitly assign a value to an instance variable, one is assigned. For primitives, the default values are 0/0.0/false and null for references.

Q: You mentioned earlier that it’s good to have a no-argument constructor so that if people call it, we can supply default values for the “missing” arguments. But aren’t their times when coming up with defaults is impossible? Is it ever a good idea to have a no-arg constructor in your class?

You are correct. There are times when a no-arg constructor is inappropriate. This is evident in the Java API(which will discuss later), where some classes lack a no-arg constructor. For example, the Color class represents a… color. Color objects are used to set or change the color of a screen font or GUI button, for example. When you create a Color instance, it is of a specific color (for example, Death-by-Chocolate Brown, Blue-Screen-of-Death Blue, Scandalous Red, and so on). You must specify the color in some way when creating a Color object :

Color color = new Color(3,45,200)

(We’re going to use three integers for RGB values here.  Color will be covered later in the Swing chapters.) What would you get if you didn’t? The Java API developers could have decided that calling a no-arg Color constructor would result in a lovely shade of mauve. But good taste won out.

If you try to create a Color without an argument:

Color color = new Color();

The compiler freaks out because it can’t find a matching no-arg constructor in the Color class.

Four Things To Remember About Constructors

1 A constructor is the code that runs when somebody says new on a class type
Mobile mobile = new Mobile();
2 A constructor must have the same name as the class, and no return type
public Mobile(){

}

3 If you don’t put a constructor in your class, the compiler puts in a default constructor. The default constructor is always a no-arg constructor.
public Mobile(){
}

4 You can have more than one constructor in your class, as long as the argument lists are different. Having more than one constructor in a class means you have overloaded constructors.
public Mobile(){}
public Mobile(double screenSize){}
public Mobile(double screenSize, int ram){}
public Mobile(double screenSize, int ram, int rom){}
public Mobile(double screenSize, int ram, int rom, int batteryCapacity){}

Q: Do constructors have to be public?

A: No. Constructors can be public, protected, private, or default (which means no access modifier at all).

Q: How could a private constructor ever be useful? Nobody could ever call it, so nobody could ever make a new object!

A: But that’s not entirely correct. Marking something private does not mean that no one can access it; it simply means that no one outside the class can access it. You’re probably thinking “Catch 22“. Only code from the same class as the class-with-private-constructor can create a new object from that class, but how do you run code from that class without first creating an object? How do you get anything done in that class? Please be patient, grasshopper.

We’ll get there in the following tutorials.

Share The Tutorial With Your Friends
Twiter
Facebook
LinkedIn
Email
WhatsApp
Skype
Reddit

Check Our Ebook for This Online Course

Advanced topics are covered in this ebook with many practical examples.