The Artima Developer Community
Sponsored Link

Object Initialization in Java
Object Initialization in the Java Language and Virtual Machine
by Bill Venners
First Published in JavaWorld, February 1998

<<  Page 3 of 8  >>

Advertisement

Constructors
The central player in object initialization is the constructor. In Java, constructors are similar to methods, but they are not methods. Like a method, a constructor has a set of parameters and a body of code. Unlike methods, however, constructors have no return type. Like methods, you can give access specifiers to constructors, but unlike methods, constructors with public, protected, or package access are not inherited by subclasses. (Also, instead of determining the ability to invoke a method, the access level of a constructor determines the ability to instantiate an object.)

Constructor basics
In the source file, a constructor looks like a method declaration in which the method has the same name as the class but has no return type. For example, here is a constructor declaration for class CoffeeCup:

// In source packet in file init/ex2/CoffeeCup.java
class CoffeeCup {
    // Constructor looks like a method declaration
    // minus the return type
    public CoffeeCup() {
        // Body of constructor
    }
    // ...
}

As with methods, you can overload constructors by varying the number, types, and order of parameters. Here is a class CoffeeCup with two constructors:

// In source packet in file init/ex3/CoffeeCup.java
class CoffeeCup {

    private int innerCoffee;

    public CoffeeCup() {
        innerCoffee = 237;
    }

    public CoffeeCup(int amount) {
        innerCoffee = amount;
    }
    // ...
}

When you instantiate an object with new, you must specify a constructor. For example, given the CoffeeCup class above that has two constructors, you could instantiate it in either of these two ways:

// In source packet in file init/ex3/Example3.java
class Example3 {
    public static void main(String[] args) {

        // Create an empty cup
        CoffeeCup cup1 = new CoffeeCup();

        // Create a cup with 355 ml of coffee in it
        CoffeeCup cup2 = new CoffeeCup(355);
    }
}

The no-arg constructor
In Java jargon, constructors that take no parameters (or no arguments) are called "no-arg constructors." In the code shown above, the first instantiation of a CoffeeCup object specifies the no-arg constructor. The second instantiation specifies the constructor that requires an int as its only parameter.

The this() invocation
From within a constructor, you can explicitly invoke another constructor from the same class by using the this() statement. You may want to do this if you have several overloaded constructors in a class, all of which must execute much of the same code. Here's an example:

// In source packet in file init/ex4/CoffeeCup.java
class CoffeeCup {

    private int innerCoffee;

    public CoffeeCup() {
        this(237); // Calls other constructor
        // Could have done more construction here
    }

    public CoffeeCup(int amount) {
        innerCoffee = amount;
    }
    // ...
}

In this example, the no-arg constructor invokes the other constructor that takes an int as its only parameter. It passes 237 to the other constructor, which assigns that value to innerCoffee.

You cannot call this() from methods, only from constructors. If you do call this()in a constructor, you must call it first, before any other code in the constructor, and you can only call it once. Any code you include after the call to this() will be executed after the invoked constructor completes.

Constructors are not methods
To further illustrate the difference between methods and constructors, consider this fact: The name of a class is a valid name for its methods. In other words, class CoffeeCup could have methods named CoffeeCup:

// In source packet in file init/ex5/CoffeeCup.java
// THIS WORKS, BUT IT IS AN EXAMPLE OF POOR METHOD NAMING
class CoffeeCup {

    private int innerCoffee;

    public CoffeeCup() {	// The constructor
        innerCoffee = 237;
    }

    public void CoffeeCup() {	// The method
        innerCoffee = 99;
    }
    // ...
}

Given the above definition of class CoffeeCup, you could legally do the following:

// In source packet in file init/ex5/Example5.java
class Example5 {
    public static void main(String[] args) {

        CoffeeCup cup = new CoffeeCup(); // invoke the constructor
        cup.CoffeeCup(); // invoke the method
    }
}

Although it is legal to give a method the same name as a class, in practice you should never do so, in part because other programmers might confuse it with a constructor, but also because it breaks many of the rules for good method design. First, a class name is not a verb; it's a noun (at least it should be a noun). Method names should be verbs. You should name methods after the action they perform, and "CoffeeCup" is not an action. Also, "CoffeeCup" doesn't follow the naming convention for methods, in which the first letter is lowercase. The purpose of this example is merely to highlight the fact that constructors aren't methods by showing that a constructor does not conflict with a method that has the same signature.

Default constructors
If you declare a class with no constructors, the compiler will automatically create a default constructor for the class. A default constructor takes no parameters (it's a no-arg constructor) and has an empty body. Because the compiler will automatically generate a default constructor if you don't declare any constructors explicitly, all classes are guaranteed to have at least one constructor. For example, if you declare a CoffeeCup class without declaring a constructor explicitly:

// In source packet in file init/ex6/CoffeeCup.java
class CoffeeCup {

    private int innerCoffee;

    public void add(int amount) {
        innerCoffee += amount;
    }
    //...
}

The compiler will generate the same class file as if you had explicitly declared a no-arg constructor with an empty body:

// In source packet in file init/ex7/CoffeeCup.java
class CoffeeCup {

    private int innerCoffee;
        public CoffeeCup() {
    }

    public void add(int amount) {
        innerCoffee += amount;
    }
    //...
}

The compiler gives default constructors the same access level as their class. In the example above, class CoffeeCup is public, so the default constructor is public. If CoffeeCup had been given package access, the default constructor would be given package access as well.

<<  Page 3 of 8  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us