10.16 Constructors

Every Java class must have a constructor. The constructor is a method with the same name as the class and no return type. For example,

 class MyClass extends SuperClass {    MyClass()    {        super();    } } 

Compiling the constructor is similar to compiling any other method except that name of the generated method is <init>. The return type of <init> is always void. The MyClass constructor compiles to

 .method <init>()V aload_0                               ; Invoke the superclass invokespecial SuperClass/<init> ()V   ; constructor return                                ; Return .end method 

The keyword super in Java is used to indicate a direct call to the constructor of the immediate superclass of the current class. This call must bypass the virtual invocation mechanism, since otherwise this definition of <init> would appear to override the SuperClass definition and the above call would recursively invoke the current method again. For this reason, the compiler uses invokespecial instead of invokevirtual to call the superclass constructor.

The syntax of the Java language requires that the call to the superclass constructor (or to some other constructor in the current class) must be the first step in the method. If the call is not provided explicitly, then the compiler adds a call to the constructor with no arguments. This is the Java language's way of ensuring that the superclass constructor is always called, one of the requirements for verification of an <init> method. Forcing the superclass constructor to be the first step in the method is actually somewhat more than the Java virtual machine requires, but it ensures that the superclass method is called.

Constructors in Java are always written without any return type. This is not a constructor:

 void MyClass() {    // Code for the method } 

The Java compiler compiles this as

 .method MyClass()V ;; Code goes here .end method 

Because a return type was specified, this compiles into a method named MyClass returning void instead of to a method named <init>. This is not a constructor.

10.16.1 Using Other Constructors in the Same Class

Instead of calling a superclass constructor, the code may call another constructor for the same class by using this:

 class AnotherClass {    int value;    /** A constructor that initializes value to the argument */    AnotherClass(int i)    {         super();          // Call the superclass constructor         value = i;    }    /** A different constructor that initializes value to 0 by     * reusing the other constructor     */    AnotherClass()    {         this(0);          // Call the other constructor    } } 

You could use this feature to get around the superclass-call requirement like this:

 class UselessClass {    UselessClass(int i)    {         this();                    // Call the other constructor    }    UselessClass()    {         this(42);                  // Call the other constructor    } } 

Nowhere in either constructor is there a call to a superclass constructor, yet this is a perfectly legal class. However, as the name implies, it is a useless class, since any attempt to use the constructor will cause the machine to call the two constructors in a mutually recursive fashion, with neither one ever returning. The JVM will rapidly run out of stack space and terminate the program.

10.16.2 Default Constructors

If no constructor is provided, then the Java compiler automatically adds a default one. Here is the smallest possible Java class:

 class Small { } 

The generated class file contains no fields, but it does contain a single method so that you can construct an instance of Small. In Oolong, this is written as

 .method <init>()V aload_0                                    ; Invoke the super's invokespecial java/lang/Object/<init>()V   ; no-args constructor return                                     ; Done .end method 

This works only when the superclass has a constructor that takes no arguments. (That constructor may itself have been generated automatically by the Java compiler.) If there is no zero argument constructor or if the constructor has access controls such that this class may not use it, then the Java compiler will report an error.

10.16.3 Field Initializers and the Constructor

Whether the constructor is automatically generated or explicitly written, the compiler adds code to perform field initializations. This code is generated after the call to the superclass constructor but before the rest of the method.

Consider this class declaration:

 class Chemistry {    /** Avogadro's number */    float avogadro = 6.022e23;    Chemistry()    {         super();         System.out.println("In Chemistry constructor");    } } 

The code generated for the Chemistry constructor is

 .method <init>()V aload_0               ; Call the superclass constructor invokespecial java/lang/Object/<init> ()V aload_0               ; Initialize avogadro ldc 6.022e23 putfield Chemistry/avogadro F ; Print the message getstatic java/lang/System/out Ljava/io/PrintStream; ldc "In Chemistry constructor" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V .end method 

The code to initialize avogadro is inserted between the call to the superclass constructor and the call to print the message. All fields are initialized before the body of the constructor begins.

The same code would be generated if the explicit superclass constructor call were eliminated: the compiler would first generate the constructor call, then the field initializations, followed by the rest of the constructor method.



Programming for the Java Virtual Machine
Programming for the Javaв„ў Virtual Machine
ISBN: 0201309726
EAN: 2147483647
Year: 1998
Pages: 158
Authors: Joshua Engel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net