Tutorial Java SCJP – #16 Constructors

In a class you can define methods, but there is a special type of methods which are used to solve a particular problem, to construct objects. Constructor methods are special because of their role and because they have a lot rules regarding declaration and usage.

Other topics that are part of this Java tutorial are accessible through Java 6 Tutorial – Contents.

Every time an object is created, a constructor is called. Based on this fact, in Java, every class has at least one constructor, even if the programmer hasn’t explicitly declared one.

The constructor methods roles are:

main role – to construct objects, meaning to allocate space in Heap

secondary role [optional] – to initialize instance variables with default (remember, that instance variables get their default value when the object is created) or given values;

Considering the given class and the main method

public class Book {
    float price;
    String title;
    String author;

    public static void main(String[] args)
    {
        //create a book
        Book b1 = new Book();
    }
}

it is obvious that in main() method it is constructed an object of type Book, referenced by the b1 reference. So, where is the constructor ?. One rule regarding constructors states that the compiler will provide a default constructor (a no-arguments one) if there are no explicitly declared constructors. The form of the default constructor, generated by the compiler, is :

    public Book()
    {

    }

Rules for declaring and calling constructors in Java

  • constructors have the same name (case-sensitive) as the parent class;
  • constructors don’t have a return type (it is logic because they always return a reference to the constructed object); methods with the same name as the class but with a return type are common methods and NOT constructors:
public class Book {
	//NOT a constructor - has a return type
    public void Book(){
        System.out.println("A simple no-sense method !");
    }
    public static void main(String[] args)
    {
        //create a book with the default constructor
        Book b1 = new Book();
        b1.Book();	//call the method
    }
}
  • constructors can be declared public or private (for a Singleton) – more on access modifiers in the next posts;
  • constructors can have no-arguments, some arguments and var-args;
    //no-arg constructor
    public Book(){
        price = 100;
        title = "Nothing";
    }
    //3 arguments constructor
    public Book(float Price, String Title, String Author){
        price = Price;
        title = Title;
        author= Author;
    }
    //2 arguments constructor
    public Book(String Title, String Author){
        price = 0;      //default value
        title = Title;
        author= Author;
    }
    //var-arg constructor
    public Book(float Price, String ... someStrings){
        //some processing here
    }
  • the default constructor is a no-arguments one;
  • if you don’t write ANY constructor, the compiler will generate the default one;
  • if you write at least one constructor (doesn’t matter its arguments) the compiler will NOT generate the default one;
  • if you write at least one constructor and you need the default one, you must write it; otherwise you get a compiler error when you try to call it:
public class Book {
    float price;
    String title;
    String author;

    //2 arguments constructor
    public Book(String Title, String Author){
        price = 0;      //default value
        title = Title;
        author = Author;
    }
    public static void main(String[] args){
        //create a book
        Book b1 = new Book();   //compiler error
                                //cannot find symbol : constructor Book()
    }

}
    public Book(float Price, String title, String Author){
        this.price = Price;     //this is optional
        this.title = title;     //must use this
        author = Author;
    }
  • the first statement in a constructor is a call to another constructor using this() or to a superclass constructor using super() (more on that in the inheritance topic); if you don’t use either this() or super(), the compiler will make the super() call; in order to understand who is super() you must know something about inheritance (next topics in this tutorial)
    //2 arguments constructor
    public Book(String Title, String Author){
	//super();	//compiler generated if you don't write it
			//in this case calls the Object class constructor
        price = 0;      //default value
        title = Title;
        author = Author;
    }

    //3 arguments constructor
    public Book(float Price, String Title, String Author){
        this(Title,Author);     //explicit call to the 2 arguments constructor
                                //MUST be the first statement
				//without it, the compiler puts super();
        price = Price;
    }
  • a constructor is called with new operator or using this() from another constructor; it is not allowed to call constructors as any other method;
        Book myBook = new Book(23,"Dune","Frank Herbert");  //ok

        Book(23,"Dune","Frank Herbert");        //compiler error
        myBook.Book(23,"Dune","Frank Herbert"); //compiler error
  • when calling other constructors with this() watch out for cross-calls that can generate infinite recursion and StackOverflowError runtime exception (some compilers may catch the problem and may generate a recursive constructor invocation error:
    public Book(String Title, String Author){
        this(0,Title,Author);      //calls the 3 arguments constructor
    }
    //3 arguments constructor
    public Book(float Price, String Title, String Author){
        this(Title,Author);     //calls the 2 arguments constructor
                                //MUST be the first statement
        price = Price;
    }
  • constructors have access to static methods or variables;
  • abstract classes have constructors;
  • when overloading constructors (defining methods with the same name but with different arguments lists) you must define them with different arguments lists (as number or as type)

 

Things important for the SCJP exam:

  • all the above rules;
  • watch out for shadowing when using constructors with arguments (see Tutorial Java SCJP – #14.1 What is shadowing a variable);
  • watch out for simple methods (no logic to do that) with a return type that look like a constructor; they are just common methods and not constructors (the distinctive mark is that they have a return type); in Java is possible to define simple methods with a name as the class;
  • after you have learned about inheritance and class hierarchies, understand constructor chaining;

A sample question. For the next code sequence

public class Book {
    float price;
    String title;
    String author;

    public void Book(){
        price = 100;
        title = "Nothing";
        author = "Anonymous";
    }

    public Book(String Title, String Author){
        this();
        price = 0;      //default value
        title = Title;
        author = Author;
    }

    public static void main(String[] args){
        Book myFirstBook = new Book("Dune","Frank Herbert");
        Book mySecondBook = new Book();
    }

}

do you see any problems ?

Put your answer in comments.

Other topics that are part of this Java tutorial are accessible through Java 6 Tutorial – Contents.