SCJP Study Guide:
Declarations, Initialization and Scoping


Printer-friendly version Printer-friendly version | Send this 
article to a friend Mail this to a friend


Previous Next vertical dots separating previous/next from contents/index/pdf Contents
XyzWs SCJP Study Guide: Constructor

Constructor


A constructor is a special kind of method that is written as a part of a class. It provides a convenient way to initialize a newly created object at the time of its creation. Once a constructor is defined for a class, it is called automatically immediately after the creation of a new object, but before the new operator completes. All Java classes must have at least one constructor, either explicitly declared in the class or an implicit default constructor.

The constructors are not inherited by subclasses, regardless if the access modifier is public, private, protected, or package. Also, instead of determining the ability to invoke a method, the access level of a constructor determines the ability to instantiate an object.

Constructor Declarations

Constructors are typically used to create an object that is an instance of a class. A constructor is written by using the following general syntax:

[access modifier] class name([formal parameter list]) [throws clause] {
   // Body of the constructor
}

where, the elements within square brackets are optional.

The definition of a constructor looks much like the definition of any other methods, with the following exceptions:

  1. A constructor does not have any return type (not even void). This is because the implicit return type of a class constructor is the class itself.
  2. The name of the constructor must be the same as the name of the class in which it is defined. This is how the Java compiler recognizes a constructor.
  3. There is no return statement in the body of the constructor.
  4. The first line of a constructor must either be a call on another constructor in the same class (using this), or a call on the superclass constructor (using super). If the first line is neither of these, the compiler automatically inserts a call to the parameterless super class constructor.
  5. The only modifiers that can be used on a constructor definition are the access modifiers public, private, and protected. Unlike methods, a constructor cannot be declared as abstract, static, final, native, strictfp, or synchronized.

However, a constructor does have a method body of the usual form, a block of statements. There are no restrictions on what statements can be used. And it can have a list of formal parameters. You can overload constructors by varying the number, types, and order of parameters. In fact, the ability to include parameters is one of the main reasons for using constructors. The parameters can provide data to be used in the construction of the object.

In the following example, the Point class contains two instance variables named x and y, and two constructors, one takes two arguments and one has no-arguments. The name of the constructor is exactly the same as the name of the class and it is declared without a return type.

class Point {
    int x;
    int y;

    Point() { }
    Point(int x, int y) { 
        this.x = x;
        this.y = y;
    }
}

Constructors are invoked by class instance creation expressions, by the conversions and concatenations caused by the string concatenation operator +, and by explicit constructor invocations from other constructors. Constructors are never invoked by method invocation expressions.

When you instantiate an object with new, you must specify a constructor. For example,

Point p = new Point(2,3);

 

Constructor Modifiers

Access to constructors is governed by access modifiers.

The use of accessibility modifiers in the constructor declaration expression specifies what other objects can create an instance of a class. A constructor can be declared using the accessibility modifiers public, private, or protected.

Access Modifier Meaning
public A class constructor when declared as public implies that any class can create an instance of the class.
private A class constructor when declared as private implies that no other classes can instantiate that class by calling that constructor. Such a class may contain public class methods sometimes also called factory methods. Those methods can construct an object and return it, but no other classes can do so.
protected A class constructor when declared as private implies that only subclasses of that class and classes that are in the same package can create instances of it.
none (default) When no access modifier is used to declare a class constructor, the package access also called default access applies. A class constructor when declared without any access modifier implies that only classes that are in the same package can construct an instance of the class.

A compile-time error occurs if the same modifier appears more than once in a constructor declaration, or if a constructor declaration has more than one of the access modifiers public, protected, and private.

If no access modifier is specified for the constructor of a normal class, the constructor has default access. If no access modifier is specified for the constructor of an enum type, the constructor is private. It is a compile-time error if the constructor of an enum type is declared public or protected.

 

Default Constructor

Every class has a constructor. The Java compiler will automatically generate a default constructor for a class provided that no other constructors have been defined by the programmer. A constructor without any parameters is known as a default constructor. The default constructor calls the no parameter constructor in the superclass (e.g., super()) and initialize all instance variables to default value depending on their data type. This action taken by a default constructor ensures that the inherited state of the object is initialized properly.

If you define any constructor for your class, no default constructor is automatically created.

The default constructor of a class has the same access modifier with which the class has been declared. For example, the default constructor of a public class is implicitly given the public access. The default constructor of a protected class is implicitly given the protected access. The default constructor of a private class is implicitly given the private access. Otherwise, the default constructor has the default access, which is implied by no access modifier.

For example,

class Point {
  int x;
  int y;
}

In the above example code, the Point class has been defined without any constructor, the compiler will automatically create an implicit default constructor. Aslo, the class modifer is default modifer (no modifer), the default constructor will have no access modifier. Therefore, this code is equivalent to the following:

class Point {
  int x;
  int y;
  Point() { //default constructor
  }
}

Once the Point class has been defined, the creation of a Point object by using the new operator along with the implicit default constructor will initialize all the fields of the object to their default value, i.e., the x and y in a Point object will be initialized to 0(the default value for the int type).

If a class defines any explicit constructors, the Java compiler does not provide an implicit default constructor to set the state of the objects. If the class requires a default constructor, the constructor must be explicitly defined within the class. For example,

class Point {
  int x;
  int y;
  Point() { 
    this.x = 100;
    this.y = 100;
  }

  public static void main(String[] args) {
    Point p = new Point();
  }
}

The above code explicitly defines a default constructor for the Point class, the compiler will not provide any default constructor to it. This constructor in the given code ensures that any object created with the expression new Point() expression will have its x and y initialized to 0.

Let's consider the following code:

class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  
  public static void main(String[] args) {
    Point p = new Point(); //compile time error.
    Point p = new Point(1,2);
  }
}

The above code defines a constructor. Therefore, the compiler will not insert a default constructor (Point() {} into the code. You have to explictly define a default constructor to avoid the compile time error.

class Point {
  int x;
  int y;

  Point() {
  }

  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  
  public static void main(String[] args) {
    Point p = new Point(); 
    Point p = new Point(1,2);
  }
}

Overloaded Constructors

Java supports name overloading for constructors. You have see it in the above example code. Therefore, a class can have any number of constructors provided they differ in their parameter lists. Typically, a constructor uses its arguments to initialize the new object's state. The compiler differentiates these constructors by taking into account the number of parameters in the list and their types.

Constructor in Subclass

Constructors are not inherited. If you extend an existing class to make a subclass, the constructors in the superclass DO NOT not become part of the subclass. Therefore, each of the subclasses must specifically implement any constructors it needs. If you don't define any constructors in the subclass, then the compiler will create a default constructor for you. However, a subclass can use the constructors of its superclass by using the super keyword. For example,

class MyPoint extends Point {
  MyPoint(int x, int y) {
    super(x,y);
  }
}

However, it must be noted that if an invocation of the super() constructor is used, it must always be the first executable statement in the constructor body. Otherwise, a compile-time error will occur.

The implied super() constructor

An object has the fields of its own class plus all fields of its parent class, grandparent class, all the way up to the root class Object. It's necessary to initialize all fields, therefore all constructors in the constructor chain must be called. The Java compiler does a lot of work in order to compile the code within the body of a constructor. If the first line of code within the body of a constructor does not contain an invocation of the super() constructor, the compiler assumes the presence of the super() statement as the first executable statement within the body of the constructor. The super() statement is an invocation of the default constructor in the superclass. Therefore, it means that the superclass must have a no-parameter constructor.

For example,

class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

class MyPoint extends Point {
  MyPoint(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

The above code will have a compile time error. That is because the compiler insert super(); statement at the first line of MyPoint(int x, int y) constructor and the Point class do not have a default constructor. See the following code:

class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

class MyPoint extends Point {
  MyPoint(int x, int y) {
    super(); //compile time error, no default constructor in superclass
    this.x = x;
    this.y = y;
  }
}

There two way to fix this problem:

  • Provide a default constructor in the superclass if you can access the superclass source code as well as the right to change.
    class Point {
      int x;
      int y;
      Point() { }
      Point(int x, int y) {
        this.x = x;
        this.y = y;
      }
    }
    
    class MyPoint extends Point {
      MyPoint(int x, int y) {
        this.x = x;
        this.y = y;
      }
    }
    
  • Insert one super() statement into the first line in subclass constructor.
    class Point {
      int x;
      int y;
      Point(int x, int y) {
        this.x = x;
        this.y = y;
      }
    }
    
    class MyPoint extends Point {
      MyPoint(int x, int y) {
        super(x, y);
        this.x = x;
        this.y = y;
      }
    }
    

Normally, you won't need to call the constructor for your parent class because it's automatically generated, but there are two cases where this is necessary.

  • You want to call a parent constructor which has parameters (the automatically generated super constructor call has no parameters).
  • There is no parameterless parent constructor because only constructors with parameters are defined in the parent class.

How to Call A Constructor in The Same Class

You may have situation that you need to call another constructor inside a contructor. For example, a constructor with few parameters will call a constructor with more parameters, giving default values for the missing parameters.

Java provides a special,predefined variable named "this" that you can use for such purposes. Use this to call other constructors in the same class. The call statement can only appear at the first line of the constructor.

class MyPoint extends Point {
  MyPoint(int x, int y) {
    super(x, y);
    this.x = x;
    this.y = y;
  }
  MyPoint() {
    this(100, 100);   //OK
  }

  MyPoint(int x) {
    this.x = x;
    this(x, 100);     //Complie time error.
  }
}

 


Previous Next vertical dots separating previous/next from contents/index/pdf Contents

  |   |